Skip to content

Commit 53ffaf4

Browse files
ahayzen-kdabLeonMatthesKDAB
authored andcommitted
cxx-qt-lib: require headers to be includes manually
This allows for cxx-qt-lib to be optional later. Related to #319
1 parent 33574c6 commit 53ffaf4

Some content is hidden

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

66 files changed

+209
-154
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions

Cargo.toml

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

1514
"examples/cargo_without_cmake",
@@ -37,7 +36,6 @@ cxx-qt-macro = { path = "crates/cxx-qt-macro", version = "0.6.0" }
3736
cxx-qt-build = { path = "crates/cxx-qt-build" }
3837
cxx-qt-gen = { path = "crates/cxx-qt-gen", version = "0.6.0" }
3938
cxx-qt-lib = { path = "crates/cxx-qt-lib" }
40-
cxx-qt-lib-headers = { path = "crates/cxx-qt-lib-headers", version = "0.6.0" }
4139
qt-build-utils = { path = "crates/qt-build-utils", version = "0.6.0" }
4240

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

crates/cxx-qt-build/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ cc.workspace = true
1717
convert_case.workspace = true
1818
cxx-gen.workspace = true
1919
cxx-qt.workspace = true
20-
cxx-qt-lib-headers.workspace = true
2120
cxx-qt-gen.workspace = true
2221
proc-macro2.workspace = true
2322
quote.workspace = true
@@ -27,6 +26,6 @@ version_check = "0.9"
2726

2827
[features]
2928
default = ["qt_gui", "qt_qml"]
30-
qt_gui = ["cxx-qt-lib-headers/qt_gui"]
31-
qt_qml = ["cxx-qt-lib-headers/qt_qml"]
29+
qt_gui = []
30+
qt_qml = []
3231
link_qt_object_files = ["qt-build-utils/link_qt_object_files"]

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

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,15 @@ fn generate_cxxqt_cpp_files(
242242
generated_file_paths
243243
}
244244

245+
/// The include directory needs to be namespaced by crate name when exporting for a C++ build system,
246+
/// but for using cargo build without a C++ build system, OUT_DIR is already namespaced by crate name.
247+
fn header_root() -> String {
248+
match env::var("CXXQT_EXPORT_DIR") {
249+
Ok(export_dir) => format!("{export_dir}/{}", env::var("CARGO_PKG_NAME").unwrap()),
250+
Err(_) => env::var("OUT_DIR").unwrap(),
251+
}
252+
}
253+
245254
fn panic_duplicate_file_and_qml_module(
246255
path: impl AsRef<Path>,
247256
uri: &str,
@@ -291,6 +300,16 @@ pub struct CxxQtBuilder {
291300
qt_modules: HashSet<String>,
292301
qml_modules: Vec<OwningQmlModule>,
293302
cc_builder: cc::Build,
303+
extra_defines: HashSet<String>,
304+
}
305+
306+
/// Options for external crates to use
307+
#[derive(Default)]
308+
pub struct CxxQtBuildersOpts {
309+
/// Any extra definitions
310+
pub defines: HashSet<String>,
311+
/// Contents, directory, file name
312+
pub headers: Vec<(String, String, String)>,
294313
}
295314

296315
impl CxxQtBuilder {
@@ -309,6 +328,7 @@ impl CxxQtBuilder {
309328
qt_modules,
310329
qml_modules: vec![],
311330
cc_builder: cc::Build::new(),
331+
extra_defines: HashSet::new(),
312332
}
313333
}
314334

@@ -426,27 +446,44 @@ impl CxxQtBuilder {
426446
self
427447
}
428448

449+
/// Build with the given extra options
450+
pub fn with_opts(mut self, opts: CxxQtBuildersOpts) -> Self {
451+
let header_root = header_root();
452+
for (file_contents, dir_name, file_name) in opts.headers {
453+
let directory = if dir_name.is_empty() {
454+
header_root.clone()
455+
} else {
456+
format!("{header_root}/{dir_name}")
457+
};
458+
std::fs::create_dir_all(directory.clone())
459+
.expect("Could not create {directory} header directory");
460+
461+
let h_path = format!("{directory}/{file_name}");
462+
let mut header = File::create(h_path).expect("Could not create header: {h_path}");
463+
write!(header, "{file_contents}").expect("Could not write header: {h_path}");
464+
}
465+
466+
// Add any of the defines
467+
self.extra_defines.extend(opts.defines);
468+
469+
self
470+
}
471+
429472
/// Generate and compile cxx-qt C++ code, as well as compile any additional files from
430473
/// [CxxQtBuilder::qobject_header] and [CxxQtBuilder::cc_builder].
431474
pub fn build(mut self) {
432475
// Ensure that the linker is setup correctly for Cargo builds
433476
qt_build_utils::setup_linker();
434477

435-
// The include directory needs to be namespaced by crate name when exporting for a C++ build system,
436-
// but for using cargo build without a C++ build system, OUT_DIR is already namespaced by crate name.
437-
let header_root = match env::var("CXXQT_EXPORT_DIR") {
438-
Ok(export_dir) => format!("{export_dir}/{}", env::var("CARGO_PKG_NAME").unwrap()),
439-
Err(_) => env::var("OUT_DIR").unwrap(),
440-
};
478+
let header_root = header_root();
441479
let generated_header_dir = format!("{header_root}/cxx-qt-gen");
442480

443481
let mut qtbuild = qt_build_utils::QtBuild::new(self.qt_modules.into_iter().collect())
444482
.expect("Could not find Qt installation");
445483
qtbuild.cargo_link_libraries(&mut self.cc_builder);
446484

447-
// Write cxx-qt-gen, cxx-qt-lib and cxx headers
485+
// Write cxx-qt and cxx headers
448486
cxx_qt::write_headers(format!("{header_root}/cxx-qt"));
449-
cxx_qt_lib_headers::write_headers(format!("{header_root}/cxx-qt-lib"));
450487
std::fs::create_dir_all(format!("{header_root}/rust"))
451488
.expect("Could not create cxx header directory");
452489
let h_path = format!("{header_root}/rust/cxx.h");
@@ -499,12 +536,12 @@ impl CxxQtBuilder {
499536
builder.flag_if_supported("-std=c++17");
500537
// MinGW requires big-obj otherwise debug builds fail
501538
builder.flag_if_supported("-Wa,-mbig-obj");
502-
// Enable Qt Gui in C++ if the feature is enabled
503-
#[cfg(feature = "qt_gui")]
504-
builder.define("CXX_QT_GUI_FEATURE", None);
505-
// Enable Qt Gui in C++ if the feature is enabled
506-
#[cfg(feature = "qt_qml")]
507-
builder.define("CXX_QT_QML_FEATURE", None);
539+
540+
// Enable any extra defines
541+
for extra_define in &self.extra_defines {
542+
builder.define(extra_define, None);
543+
}
544+
508545
for include_dir in qtbuild.include_paths() {
509546
builder.include(&include_dir);
510547
}

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

Lines changed: 0 additions & 17 deletions
This file was deleted.

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

Lines changed: 0 additions & 112 deletions
This file was deleted.

crates/cxx-qt-lib/Cargo.toml

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

2930
[build-dependencies]
3031
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-lib-headers/qt_gui"]
41-
qt_qml = ["cxx-qt-lib-headers/qt_qml"]
40+
qt_gui = ["cxx-qt-build/qt_gui"]
41+
qt_qml = ["cxx-qt-build/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: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,38 @@ fn main() {
263263
println!("cargo:rerun-if-changed=src/qt_types.cpp");
264264
println!("cargo:rerun-if-changed=src/assertion_utils.h");
265265

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+
266287
// Write this library's manually written C++ headers to files and add them to include paths
267-
let out_dir = std::env::var("OUT_DIR").unwrap();
268-
cxx_qt_lib_headers::write_headers(format!("{out_dir}/cxx-qt-lib"));
269-
builder.include(out_dir);
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);
270298

271299
// Enable Qt Gui in C++ if the feature is enabled
272300
if feature_qt_gui_enabled {

0 commit comments

Comments
 (0)