Skip to content

Commit 66c1972

Browse files
committed
qt-build-utils: Add an option to use CMake instead of QMake
This is needed for scenarios where the CMake packaging for Qt is better than what QMake can handle, e.g. split Qt installations where the modules live in different directories. A new optional feature is added to cxx-qt-build to prefer CMake for most operations related to linking/including Qt modules. QMake is still the default. Fixes #1153.
1 parent e84662a commit 66c1972

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121

2222
- `QDateTime::from_string` to parse `QDateTime` from a `QString`.
2323
- Support for further types: `QUuid`
24+
- Optional feature `cmake` to cxx-qt-build to prefer CMake instead of QMake for finding and linking to Qt.
2425

2526
### Fixed
2627

crates/cxx-qt-build/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ serde_json = "1.0"
2727

2828
[features]
2929
link_qt_object_files = ["qt-build-utils/link_qt_object_files"]
30+
cmake = ["qt-build-utils/cmake"]
3031

3132
[lints]
3233
workspace = true

crates/qt-build-utils/Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ rust-version.workspace = true
1717
cc.workspace = true
1818
versions = "6.3"
1919
thiserror.workspace = true
20+
cmake-package = { version = "0.1.5", optional = true }
2021

2122
[features]
2223
# When Cargo links an executable, whether a bin crate or test executable,
@@ -31,5 +32,9 @@ thiserror.workspace = true
3132
# When linking Qt dynamically, this makes no difference.
3233
link_qt_object_files = []
3334

35+
# Prefer using CMake to find Qt modules, instead of using qmake.
36+
# This may be desirable in certain installations.
37+
cmake = ["cmake-package"]
38+
3439
[lints]
3540
workspace = true

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

+45
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,30 @@ impl QtBuild {
558558
/// Get the include paths for Qt, including Qt module subdirectories. This is intended
559559
/// to be passed to whichever tool you are using to invoke the C++ compiler.
560560
pub fn include_paths(&self) -> Vec<PathBuf> {
561+
#[cfg(feature = "cmake")]
562+
{
563+
let Ok(package) = cmake_package::find_package(format!("Qt{}", self.version.major))
564+
.components(self.qt_modules.clone())
565+
.find()
566+
else {
567+
return Vec::default();
568+
};
569+
570+
let mut paths = Vec::new();
571+
for qt_module in &self.qt_modules {
572+
if let Some(target) = package.target(format!("Qt::{}", qt_module)) {
573+
paths.extend(target.include_directories);
574+
}
575+
}
576+
577+
return paths
578+
.iter()
579+
.map(PathBuf::from)
580+
// Only add paths if they exist
581+
.filter(|path| path.exists())
582+
.collect();
583+
}
584+
561585
let root_path = self.qmake_query("QT_INSTALL_HEADERS");
562586
let lib_path = self.qmake_query("QT_INSTALL_LIBS");
563587
let mut paths = Vec::new();
@@ -591,6 +615,27 @@ impl QtBuild {
591615
/// Lazy load the path of a Qt executable tool
592616
/// Skip doing this in the constructor because not every user of this crate will use each tool
593617
fn get_qt_tool(&self, tool_name: &str) -> Result<String, ()> {
618+
#[cfg(feature = "cmake")]
619+
{
620+
// QML tools live in the QML target, of course
621+
let tools_component = if tool_name.contains("qml") {
622+
"QmlTools"
623+
} else {
624+
"CoreTools"
625+
};
626+
627+
let Ok(package) = cmake_package::find_package(format!("Qt{}", self.version.major))
628+
.components([tools_component.into()])
629+
.find()
630+
else {
631+
return Err(());
632+
};
633+
let Some(target) = package.target(format!("Qt6::{}", tool_name)) else {
634+
return Err(());
635+
};
636+
return target.location.ok_or(());
637+
}
638+
594639
// "qmake -query" exposes a list of paths that describe where Qt executables and libraries
595640
// are located, as well as where new executables & libraries should be installed to.
596641
// We can use these variables to find any Qt tool.

examples/cargo_without_cmake/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ cxx-qt-lib = { workspace = true, features = ["full"] }
3131
# Use `cxx-qt-build = "0.7"` 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+
35+
[features]
36+
cmake = ["cxx-qt-build/cmake"]

0 commit comments

Comments
 (0)