Skip to content

Commit 1ba45c5

Browse files
ahayzen-kdabLeonMatthesKDAB
authored andcommitted
cxx-qt-lib: keep headers split otherwise Windows fails to build
When cxx-qt-lib is a build dependency we have a failure with a missing dll.
1 parent 53ffaf4 commit 1ba45c5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+172
-155
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ members = [
99
"crates/cxx-qt-build",
1010
"crates/cxx-qt-gen",
1111
"crates/cxx-qt-lib",
12+
"crates/cxx-qt-lib-headers",
1213
"crates/qt-build-utils",
1314

1415
"examples/cargo_without_cmake",
@@ -36,6 +37,7 @@ cxx-qt-macro = { path = "crates/cxx-qt-macro", version = "0.6.0" }
3637
cxx-qt-build = { path = "crates/cxx-qt-build" }
3738
cxx-qt-gen = { path = "crates/cxx-qt-gen", version = "0.6.0" }
3839
cxx-qt-lib = { path = "crates/cxx-qt-lib" }
40+
cxx-qt-lib-headers = { path = "crates/cxx-qt-lib-headers", version = "0.6.0" }
3941
qt-build-utils = { path = "crates/qt-build-utils", version = "0.6.0" }
4042

4143
cc = { version = "1.0.86", features = ["parallel"] }

crates/cxx-qt-lib-headers/Cargo.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# SPDX-FileCopyrightText: 2022 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
2+
# SPDX-FileContributor: Be Wilson <[email protected]>
3+
#
4+
# SPDX-License-Identifier: MIT OR Apache-2.0
5+
[package]
6+
name = "cxx-qt-lib-headers"
7+
version.workspace = true
8+
authors = ["Andrew Hayzen <[email protected]>", "Be Wilson <[email protected]>"]
9+
edition.workspace = true
10+
license.workspace = true
11+
description = "A small crate for cxx-qt-lib and cxx-qt-build to share cxx-qt-lib's C++ headers"
12+
repository.workspace = true
13+
14+
[features]
15+
default = []
16+
qt_gui = ["cxx-qt-build/qt_gui"]
17+
qt_qml = ["cxx-qt-build/qt_qml"]
18+
19+
[dependencies]
20+
cxx-qt-build.workspace = true

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

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// SPDX-FileCopyrightText: 2022 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
2+
// SPDX-FileContributor: Be Wilson <[email protected]>
3+
//
4+
// SPDX-License-Identifier: MIT OR Apache-2.0
5+
6+
#![deny(missing_docs)]
7+
8+
//! The headers for cxx-qt-lib, when combined into cxx-qt-lib crate this fails to build on Windows.
9+
//! The issue occurs when cxx-qt-lib is a build-dependency of an example
10+
11+
/// Retrieves the headers for cxx-qt-lib
12+
///
13+
/// These can be passed into [cxx_qt_build::CxxQtBuilder].
14+
pub fn build_opts() -> cxx_qt_build::CxxQtBuildersOpts {
15+
let mut opts = cxx_qt_build::CxxQtBuildersOpts::default();
16+
17+
for (file_contents, file_name) in [
18+
(include_str!("../include/core/qbytearray.h"), "qbytearray.h"),
19+
(
20+
include_str!("../include/core/qcoreapplication.h"),
21+
"qcoreapplication.h",
22+
),
23+
(include_str!("../include/core/qdate.h"), "qdate.h"),
24+
(include_str!("../include/core/qdatetime.h"), "qdatetime.h"),
25+
(include_str!("../include/core/qhash.h"), "qhash.h"),
26+
(include_str!("../include/core/qline.h"), "qline.h"),
27+
(include_str!("../include/core/qlinef.h"), "qlinef.h"),
28+
(include_str!("../include/core/qlist.h"), "qlist.h"),
29+
(
30+
include_str!("../include/core/qlist_qvector.h"),
31+
"qlist_qvector.h",
32+
),
33+
(include_str!("../include/core/qmap.h"), "qmap.h"),
34+
(include_str!("../include/core/qmargins.h"), "qmargins.h"),
35+
(include_str!("../include/core/qmarginsf.h"), "qmarginsf.h"),
36+
(
37+
include_str!("../include/core/qmetaobjectconnection.h"),
38+
"qmetaobjectconnection.h",
39+
),
40+
(
41+
include_str!("../include/core/qmodelindex.h"),
42+
"qmodelindex.h",
43+
),
44+
#[cfg(feature = "qt_gui")]
45+
(include_str!("../include/gui/qpen.h"), "qpen.h"),
46+
(
47+
include_str!("../include/core/qpersistentmodelindex.h"),
48+
"qpersistentmodelindex.h",
49+
),
50+
(include_str!("../include/core/qpoint.h"), "qpoint.h"),
51+
(include_str!("../include/core/qpointf.h"), "qpointf.h"),
52+
(include_str!("../include/core/qrect.h"), "qrect.h"),
53+
(include_str!("../include/core/qrectf.h"), "qrectf.h"),
54+
(include_str!("../include/core/qset.h"), "qset.h"),
55+
(include_str!("../include/core/qsize.h"), "qsize.h"),
56+
(include_str!("../include/core/qsizef.h"), "qsizef.h"),
57+
(include_str!("../include/core/qstring.h"), "qstring.h"),
58+
(
59+
include_str!("../include/core/qstringlist.h"),
60+
"qstringlist.h",
61+
),
62+
(include_str!("../include/core/qt.h"), "qt.h"),
63+
(include_str!("../include/core/qtime.h"), "qtime.h"),
64+
(include_str!("../include/core/qtimezone.h"), "qtimezone.h"),
65+
(include_str!("../include/core/qurl.h"), "qurl.h"),
66+
(include_str!("../include/core/qvariant.h"), "qvariant.h"),
67+
(include_str!("../include/core/qvector.h"), "qvector.h"),
68+
#[cfg(feature = "qt_gui")]
69+
(include_str!("../include/gui/qcolor.h"), "qcolor.h"),
70+
#[cfg(feature = "qt_gui")]
71+
(include_str!("../include/gui/qfont.h"), "qfont.h"),
72+
#[cfg(feature = "qt_gui")]
73+
(
74+
include_str!("../include/gui/qguiapplication.h"),
75+
"qguiapplication.h",
76+
),
77+
#[cfg(feature = "qt_gui")]
78+
(include_str!("../include/gui/qimage.h"), "qimage.h"),
79+
#[cfg(feature = "qt_gui")]
80+
(include_str!("../include/gui/qpolygon.h"), "qpolygon.h"),
81+
(include_str!("../include/gui/qpolygonf.h"), "qpolygonf.h"),
82+
(
83+
include_str!("../include/gui/qpainterpath.h"),
84+
"qpainterpath.h",
85+
),
86+
#[cfg(feature = "qt_gui")]
87+
(include_str!("../include/gui/qpainter.h"), "qpainter.h"),
88+
#[cfg(feature = "qt_gui")]
89+
(include_str!("../include/gui/qvector2d.h"), "qvector2d.h"),
90+
#[cfg(feature = "qt_gui")]
91+
(include_str!("../include/gui/qvector3d.h"), "qvector3d.h"),
92+
#[cfg(feature = "qt_gui")]
93+
(include_str!("../include/gui/qvector4d.h"), "qvector4d.h"),
94+
#[cfg(feature = "qt_qml")]
95+
(
96+
include_str!("../include/qml/qqmlapplicationengine.h"),
97+
"qqmlapplicationengine.h",
98+
),
99+
#[cfg(feature = "qt_qml")]
100+
(include_str!("../include/qml/qqmlengine.h"), "qqmlengine.h"),
101+
(include_str!("../include/common.h"), "common.h"),
102+
] {
103+
opts.headers.push((
104+
file_contents.to_owned(),
105+
"cxx-qt-lib".to_owned(),
106+
file_name.to_owned(),
107+
));
108+
}
109+
110+
#[cfg(feature = "qt_gui")]
111+
opts.defines.insert("CXX_QT_GUI_FEATURE".to_owned());
112+
#[cfg(feature = "qt_qml")]
113+
opts.defines.insert("CXX_QT_QML_FEATURE".to_owned());
114+
115+
opts
116+
}

crates/cxx-qt-lib/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ exclude = [ "**/generate.sh" ]
1919
[dependencies]
2020
cxx.workspace = true
2121
cxx-qt.workspace = true
22-
cxx-qt-build.workspace = true
2322
bytes = { version = "1.4", optional = true }
2423
chrono = { version = "0.4.27", optional = true }
2524
http = { version = "1.0", optional = true }
@@ -29,6 +28,7 @@ url = { version = "2.3", optional = true }
2928

3029
[build-dependencies]
3130
cxx-build.workspace = true
31+
cxx-qt-lib-headers.workspace = true
3232
qt-build-utils.workspace = true
3333

3434
[features]
@@ -37,8 +37,8 @@ bytes = ["dep:bytes"]
3737
chrono = ["dep:chrono"]
3838
http = ["dep:http"]
3939
rgb = ["dep:rgb"]
40-
qt_gui = ["cxx-qt-build/qt_gui"]
41-
qt_qml = ["cxx-qt-build/qt_qml"]
40+
qt_gui = ["cxx-qt-lib-headers/qt_gui"]
41+
qt_qml = ["cxx-qt-lib-headers/qt_qml"]
4242
time = ["dep:time"]
4343
url = ["dep:url"]
4444
link_qt_object_files = ["qt-build-utils/link_qt_object_files"]

crates/cxx-qt-lib/build.rs

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
//
44
// SPDX-License-Identifier: MIT OR Apache-2.0
55

6+
use std::{fs::File, io::Write};
7+
68
fn main() {
79
let feature_qt_gui_enabled = std::env::var("CARGO_FEATURE_QT_GUI").is_ok();
810
let feature_qt_qml_enabled = std::env::var("CARGO_FEATURE_QT_QML").is_ok();
@@ -263,38 +265,22 @@ fn main() {
263265
println!("cargo:rerun-if-changed=src/qt_types.cpp");
264266
println!("cargo:rerun-if-changed=src/assertion_utils.h");
265267

266-
fn copy_dir(src: impl AsRef<std::path::Path>, dest: impl AsRef<std::path::Path>) {
267-
let dest = dest.as_ref();
268-
let src = src.as_ref();
269-
if src.is_dir() {
270-
std::fs::create_dir_all(dest).expect("could not create directory {dest}");
271-
for entry in std::fs::read_dir(src).expect("could not read dir {src}") {
272-
let entry = entry.expect("could not retrieve entry for dir {src}");
273-
let path = entry.path();
274-
let file_name = entry
275-
.file_name()
276-
.into_string()
277-
.expect("cannot convert OsString to String");
278-
let dest = dest.display();
279-
if path.is_file() {
280-
std::fs::copy(path, format!("{dest}/{file_name}"))
281-
.expect("could not copy {path}");
282-
}
283-
}
284-
}
285-
}
286-
287268
// Write this library's manually written C++ headers to files and add them to include paths
288-
let include_out_dir = format!("{}/include", std::env::var("OUT_DIR").unwrap());
289-
copy_dir("include/core", format!("{include_out_dir}/cxx-qt-lib"));
290-
copy_dir("include/gui", format!("{include_out_dir}/cxx-qt-lib"));
291-
copy_dir("include/qml", format!("{include_out_dir}/cxx-qt-lib"));
292-
std::fs::copy(
293-
"include/common.h",
294-
format!("{include_out_dir}/cxx-qt-lib/common.h"),
295-
)
296-
.expect("could not copy common.h");
297-
builder.include(include_out_dir);
269+
let header_root = format!("{}/include", std::env::var("OUT_DIR").unwrap());
270+
for (file_contents, dir_name, file_name) in cxx_qt_lib_headers::build_opts().headers {
271+
let directory = if dir_name.is_empty() {
272+
header_root.clone()
273+
} else {
274+
format!("{header_root}/{dir_name}")
275+
};
276+
std::fs::create_dir_all(directory.clone())
277+
.expect("Could not create {directory} header directory");
278+
279+
let h_path = format!("{directory}/{file_name}");
280+
let mut header = File::create(h_path).expect("Could not create header: {h_path}");
281+
write!(header, "{file_contents}").expect("Could not write header: {h_path}");
282+
}
283+
builder.include(header_root);
298284

299285
// Enable Qt Gui in C++ if the feature is enabled
300286
if feature_qt_gui_enabled {

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

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -20,110 +20,3 @@ pub use crate::gui::*;
2020
mod qml;
2121
#[cfg(feature = "qt_qml")]
2222
pub use crate::qml::*;
23-
24-
/// Retrieves the headers for cxx-qt-lib
25-
///
26-
/// These can be passed into [cxx_qt_build::CxxQtBuilder].
27-
pub fn build_opts() -> cxx_qt_build::CxxQtBuildersOpts {
28-
let mut opts = cxx_qt_build::CxxQtBuildersOpts::default();
29-
30-
for (file_contents, file_name) in [
31-
(include_str!("../include/core/qbytearray.h"), "qbytearray.h"),
32-
(
33-
include_str!("../include/core/qcoreapplication.h"),
34-
"qcoreapplication.h",
35-
),
36-
(include_str!("../include/core/qdate.h"), "qdate.h"),
37-
(include_str!("../include/core/qdatetime.h"), "qdatetime.h"),
38-
(include_str!("../include/core/qhash.h"), "qhash.h"),
39-
(include_str!("../include/core/qline.h"), "qline.h"),
40-
(include_str!("../include/core/qlinef.h"), "qlinef.h"),
41-
(include_str!("../include/core/qlist.h"), "qlist.h"),
42-
(
43-
include_str!("../include/core/qlist_qvector.h"),
44-
"qlist_qvector.h",
45-
),
46-
(include_str!("../include/core/qmap.h"), "qmap.h"),
47-
(include_str!("../include/core/qmargins.h"), "qmargins.h"),
48-
(include_str!("../include/core/qmarginsf.h"), "qmarginsf.h"),
49-
(
50-
include_str!("../include/core/qmetaobjectconnection.h"),
51-
"qmetaobjectconnection.h",
52-
),
53-
(
54-
include_str!("../include/core/qmodelindex.h"),
55-
"qmodelindex.h",
56-
),
57-
#[cfg(feature = "qt_gui")]
58-
(include_str!("../include/gui/qpen.h"), "qpen.h"),
59-
(
60-
include_str!("../include/core/qpersistentmodelindex.h"),
61-
"qpersistentmodelindex.h",
62-
),
63-
(include_str!("../include/core/qpoint.h"), "qpoint.h"),
64-
(include_str!("../include/core/qpointf.h"), "qpointf.h"),
65-
(include_str!("../include/core/qrect.h"), "qrect.h"),
66-
(include_str!("../include/core/qrectf.h"), "qrectf.h"),
67-
(include_str!("../include/core/qset.h"), "qset.h"),
68-
(include_str!("../include/core/qsize.h"), "qsize.h"),
69-
(include_str!("../include/core/qsizef.h"), "qsizef.h"),
70-
(include_str!("../include/core/qstring.h"), "qstring.h"),
71-
(
72-
include_str!("../include/core/qstringlist.h"),
73-
"qstringlist.h",
74-
),
75-
(include_str!("../include/core/qt.h"), "qt.h"),
76-
(include_str!("../include/core/qtime.h"), "qtime.h"),
77-
(include_str!("../include/core/qtimezone.h"), "qtimezone.h"),
78-
(include_str!("../include/core/qurl.h"), "qurl.h"),
79-
(include_str!("../include/core/qvariant.h"), "qvariant.h"),
80-
(include_str!("../include/core/qvector.h"), "qvector.h"),
81-
#[cfg(feature = "qt_gui")]
82-
(include_str!("../include/gui/qcolor.h"), "qcolor.h"),
83-
#[cfg(feature = "qt_gui")]
84-
(include_str!("../include/gui/qfont.h"), "qfont.h"),
85-
#[cfg(feature = "qt_gui")]
86-
(
87-
include_str!("../include/gui/qguiapplication.h"),
88-
"qguiapplication.h",
89-
),
90-
#[cfg(feature = "qt_gui")]
91-
(include_str!("../include/gui/qimage.h"), "qimage.h"),
92-
#[cfg(feature = "qt_gui")]
93-
(include_str!("../include/gui/qpolygon.h"), "qpolygon.h"),
94-
(include_str!("../include/gui/qpolygonf.h"), "qpolygonf.h"),
95-
(
96-
include_str!("../include/gui/qpainterpath.h"),
97-
"qpainterpath.h",
98-
),
99-
#[cfg(feature = "qt_gui")]
100-
(include_str!("../include/gui/qpainter.h"), "qpainter.h"),
101-
#[cfg(feature = "qt_gui")]
102-
(include_str!("../include/gui/qvector2d.h"), "qvector2d.h"),
103-
#[cfg(feature = "qt_gui")]
104-
(include_str!("../include/gui/qvector3d.h"), "qvector3d.h"),
105-
#[cfg(feature = "qt_gui")]
106-
(include_str!("../include/gui/qvector4d.h"), "qvector4d.h"),
107-
#[cfg(feature = "qt_qml")]
108-
(
109-
include_str!("../include/qml/qqmlapplicationengine.h"),
110-
"qqmlapplicationengine.h",
111-
),
112-
#[cfg(feature = "qt_qml")]
113-
(include_str!("../include/qml/qqmlengine.h"), "qqmlengine.h"),
114-
(include_str!("../include/common.h"), "common.h"),
115-
] {
116-
opts.headers.push((
117-
file_contents.to_owned(),
118-
"cxx-qt-lib".to_owned(),
119-
file_name.to_owned(),
120-
));
121-
}
122-
123-
#[cfg(feature = "qt_gui")]
124-
opts.defines.insert("CXX_QT_GUI_FEATURE".to_owned());
125-
#[cfg(feature = "qt_qml")]
126-
opts.defines.insert("CXX_QT_QML_FEATURE".to_owned());
127-
128-
opts
129-
}

examples/cargo_without_cmake/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ cxx-qt-lib.workspace = true
3131
# Use `cxx-qt-build = "0.6"` here instead!
3232
# The link_qt_object_files feature is required for statically linking Qt 6.
3333
cxx-qt-build = { workspace = true, features = [ "link_qt_object_files" ] }
34-
# Use `cxx-qt-lib = "0.6"` here instead!
35-
cxx-qt-lib.workspace = true
34+
# Use `cxx-qt-lib-headers = "0.6"` here instead!
35+
cxx-qt-lib-headers.workspace = true

examples/cargo_without_cmake/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn main() {
2020
qml_files: &["qml/main.qml"],
2121
..Default::default()
2222
})
23-
.with_opts(cxx_qt_lib::build_opts())
23+
.with_opts(cxx_qt_lib_headers::build_opts())
2424
.build();
2525
}
2626
// ANCHOR_END: book_cargo_executable_build_rs

examples/demo_threading/rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ uuid = { version = "1.2", features = ["serde", "v4"] }
2525

2626
[build-dependencies]
2727
cxx-qt-build.workspace = true
28-
cxx-qt-lib.workspace = true
28+
cxx-qt-lib-headers.workspace = true
2929

3030
[features]
3131
link_qt_object_files = [ "cxx-qt-build/link_qt_object_files" ]

examples/demo_threading/rust/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,6 @@ fn main() {
4646
],
4747
..Default::default()
4848
})
49-
.with_opts(cxx_qt_lib::build_opts())
49+
.with_opts(cxx_qt_lib_headers::build_opts())
5050
.build();
5151
}

examples/qml_features/rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ serde_json.workspace = true
2222

2323
[build-dependencies]
2424
cxx-qt-build.workspace = true
25-
cxx-qt-lib.workspace = true
25+
cxx-qt-lib-headers.workspace = true
2626

2727
[features]
2828
link_qt_object_files = [ "cxx-qt-build/link_qt_object_files" ]

0 commit comments

Comments
 (0)