From 3d31a6e8461b9358107f5907f112bde19828d3f3 Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Sat, 1 Jul 2023 15:10:33 +0200 Subject: [PATCH 01/14] Correctly interpret QT_INSTALL_PREFIX from prl files. --- crates/cxx-qt-build/Cargo.toml | 1 + crates/cxx-qt-build/src/lib.rs | 2 +- crates/cxx-qt-lib/build.rs | 25 +++++---- crates/qt-build-utils/Cargo.toml | 4 ++ crates/qt-build-utils/src/lib.rs | 67 +++++++++++++++-------- crates/qt-build-utils/src/parse_cflags.rs | 21 ++++--- 6 files changed, 76 insertions(+), 44 deletions(-) diff --git a/crates/cxx-qt-build/Cargo.toml b/crates/cxx-qt-build/Cargo.toml index cfa20e682..5c5cdf238 100644 --- a/crates/cxx-qt-build/Cargo.toml +++ b/crates/cxx-qt-build/Cargo.toml @@ -28,3 +28,4 @@ version_check = "0.9" default = ["qt_gui", "qt_qml"] qt_gui = ["cxx-qt-lib-headers/qt_gui"] qt_qml = ["cxx-qt-lib-headers/qt_qml"] +include_qt_objects = ["qt-build-utils/include_qt_objects"] diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index d7cdd06b0..013903a80 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -399,7 +399,7 @@ impl CxxQtBuilder { let mut qtbuild = qt_build_utils::QtBuild::new(self.qt_modules.into_iter().collect()) .expect("Could not find Qt installation"); - qtbuild.cargo_link_libraries(); + qtbuild.cargo_link_libraries(&mut self.cc_builder); // Write cxx-qt-gen, cxx-qt-lib and cxx headers cxx_qt_gen::write_headers(format!("{header_root}/cxx-qt-common")); diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index 8a1cb2253..04a63415e 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -19,18 +19,6 @@ fn main() { qt_modules.push("Qml".to_owned()); } - let qtbuild = qt_build_utils::QtBuild::new(qt_modules).expect("Could not find Qt installation"); - qtbuild.cargo_link_libraries(); - // Required for tests - qt_build_utils::setup_linker(); - - // Find the Qt version and tell the Rust compiler - // this allows us to have conditional Rust code - println!( - "cargo:rustc-cfg=qt_version_major=\"{}\"", - qtbuild.version().major - ); - let mut rust_bridges = vec![ "core/qbytearray", "core/qcoreapplication", @@ -183,6 +171,8 @@ fn main() { println!("cargo:rerun-if-changed=src/{bridge}.rs"); } + let qtbuild = qt_build_utils::QtBuild::new(qt_modules).expect("Could not find Qt installation"); + for include_path in qtbuild.include_paths() { cxx_build::CFG .exported_header_dirs @@ -192,6 +182,17 @@ fn main() { let mut builder = cxx_build::bridges(rust_bridges.iter().map(|bridge| format!("src/{bridge}.rs"))); + qtbuild.cargo_link_libraries(&mut builder); + // Required for tests + qt_build_utils::setup_linker(); + + // Find the Qt version and tell the Rust compiler + // this allows us to have conditional Rust code + println!( + "cargo:rustc-cfg=qt_version_major=\"{}\"", + qtbuild.version().major + ); + let mut cpp_files = vec![ "core/qbytearray", "core/qcoreapplication", diff --git a/crates/qt-build-utils/Cargo.toml b/crates/qt-build-utils/Cargo.toml index fd7777086..437ad09c5 100644 --- a/crates/qt-build-utils/Cargo.toml +++ b/crates/qt-build-utils/Cargo.toml @@ -13,5 +13,9 @@ description = "Build script helper for linking Qt libraries and using moc code g repository.workspace = true [dependencies] +cc = "1.0.74" versions = "4.1.0" thiserror = "1.0" + +[features] +include_qt_objects = [] diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index c0e3566f4..462c52059 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -306,8 +306,43 @@ impl QtBuild { .to_string() } + fn cargo_link_qt_library( + &self, + builder: &mut cc::Build, + name: &str, + prefix_path: &str, + lib_path: &str, + link_lib: &str, + prl_path: &str, + ) { + println!("cargo:rustc-link-lib={link_lib}"); + + match std::fs::read_to_string(&prl_path) { + Ok(prl) => { + for line in prl.lines() { + if let Some(line) = line.strip_prefix("QMAKE_PRL_LIBS = ") { + parse_cflags::parse_libs_cflags( + builder, + name, + line.replace(r"$$[QT_INSTALL_LIBS]", &lib_path) + .replace(r"$$[QT_INSTALL_PREFIX]", &prefix_path) + .as_bytes(), + ); + } + } + } + Err(e) => { + println!( + "cargo:warning=Could not open {} file to read libraries to link: {}", + &prl_path, e + ); + } + } + } + /// Tell Cargo to link each Qt module. - pub fn cargo_link_libraries(&self) { + pub fn cargo_link_libraries(&self, builder: &mut cc::Build) { + let prefix_path = self.qmake_query("QT_INSTALL_PREFIX"); let lib_path = self.qmake_query("QT_INSTALL_LIBS"); println!("cargo:rustc-link-search={lib_path}"); @@ -350,28 +385,14 @@ impl QtBuild { ) }; - println!("cargo:rustc-link-lib={link_lib}"); - - match std::fs::read_to_string(&prl_path) { - Ok(prl) => { - for line in prl.lines() { - if let Some(line) = line.strip_prefix("QMAKE_PRL_LIBS = ") { - parse_cflags::parse_libs_cflags( - &format!("Qt{}{qt_module}", self.version.major), - line.replace(r"$$[QT_INSTALL_LIBS]", &lib_path) - .replace(r"$$[QT_INSTALL_PREFIX]", &lib_path) - .as_bytes(), - ); - } - } - } - Err(e) => { - println!( - "cargo:warning=Could not open {} file to read libraries to link: {}", - &prl_path, e - ); - } - } + self.cargo_link_qt_library( + builder, + &format!("Qt{}{qt_module}", self.version.major), + &prefix_path, + &lib_path, + &link_lib, + &prl_path, + ); } } diff --git a/crates/qt-build-utils/src/parse_cflags.rs b/crates/qt-build-utils/src/parse_cflags.rs index 0346380af..7c838ee82 100644 --- a/crates/qt-build-utils/src/parse_cflags.rs +++ b/crates/qt-build-utils/src/parse_cflags.rs @@ -103,7 +103,7 @@ fn split_flags(link_args: &[u8]) -> Vec { words } -pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8]) { +pub(crate) fn parse_libs_cflags(_builder: &mut cc::Build, name: &str, link_args: &[u8]) { let mut is_msvc = false; let target = env::var("TARGET"); if let Ok(target) = &target { @@ -167,13 +167,18 @@ pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8]) { if let (Some(dir), Some(file_name), Ok(target)) = (path.parent(), path.file_name(), &target) { - match extract_lib_from_filename(target, &file_name.to_string_lossy()) { - Some(lib_basename) => { - println!("cargo:rustc-link-search={}", dir.display()); - println!("cargo:rustc-link-lib={lib_basename}"); - } - None => { - println!("cargo:warning=File path {} found in .prl file for {name}, but could not extract library base name to pass to linker command line", path.display()); + if file_name.to_string_lossy().ends_with(".o") { + #[cfg(feature = "include_qt_objects")] + _builder.object(path); + } else { + match extract_lib_from_filename(target, &file_name.to_string_lossy()) { + Some(lib_basename) => { + println!("cargo:rustc-link-search={}", dir.display()); + println!("cargo:rustc-link-lib={lib_basename}"); + } + None => { + println!("cargo:warning=File path {} found in .prl file for {name}, but could not extract library base name to pass to linker command line", path.display()); + } } } } From af5656d7f2cb7b1d5e6901226b7263d9568d7feb Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Sat, 1 Jul 2023 15:12:43 +0200 Subject: [PATCH 02/14] Some prl files do not follow the assumed pattern. Instead look for the files by iterating over the directory entries. --- crates/qt-build-utils/src/lib.rs | 35 ++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index 462c52059..d9413be2d 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -340,6 +340,36 @@ impl QtBuild { } } + /// Some prl files don't follow a consistent naming scheme. Try to find it by looking at all files in lib_path. + fn find_qt_module_prl(&self, lib_path: &str, prefix: &str, version_major: u32, qt_module: &str) -> String { + match Path::new(lib_path).read_dir() { + Ok(lib_dir) => { + for entry in lib_dir { + match entry { + Ok(entry) => { + let file_name = entry.file_name(); + let file_name = file_name.to_string_lossy(); + let prl_file = file_name.ends_with(".prl"); + let matches_module = file_name + .contains(&format!("Qt{}{}", self.version.major, qt_module)); + if prl_file && matches_module { + return entry.path().display().to_string(); + } + } + Err(e) => { + println!("cargo:warning=Could not read {} entry: {}", lib_path, e); + } + } + } + } + Err(e) => { + println!("cargo:warning=Could not read dir {}: {}", lib_path, e); + } + } + + format!("{}/{}Qt{}{}.prl",lib_path, prefix, version_major, qt_module) + } + /// Tell Cargo to link each Qt module. pub fn cargo_link_libraries(&self, builder: &mut cc::Build) { let prefix_path = self.qmake_query("QT_INSTALL_PREFIX"); @@ -378,10 +408,7 @@ impl QtBuild { } else { ( format!("Qt{}{qt_module}", self.version.major), - format!( - "{}/{}Qt{}{}.prl", - lib_path, prefix, self.version.major, qt_module - ), + self.find_qt_module_prl(&lib_path, prefix, self.version.major, qt_module), ) }; From ecd2c54b96175de67f1afc8bc51f04f782dc700b Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Sat, 1 Jul 2023 15:14:22 +0200 Subject: [PATCH 03/14] The libqwasm.prl file must be parsed for the emscripten target. --- crates/qt-build-utils/src/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index d9413be2d..14095945a 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -421,6 +421,23 @@ impl QtBuild { &prl_path, ); } + + let emscripten_targeted = match env::var("CARGO_CFG_TARGET_OS") { + Ok(val) => val == "emscripten", + Err(_) => false, + }; + if emscripten_targeted { + let platforms_path = format!("{}/platforms", self.qmake_query("QT_INSTALL_PLUGINS")); + println!("cargo:rustc-link-search={platforms_path}"); + self.cargo_link_qt_library( + builder, + "qwasm", + &prefix_path, + &lib_path, + "qwasm", + &format!("{platforms_path}/libqwasm.prl"), + ); + } } /// Get the include paths for Qt, including Qt module subdirectories. This is intended From 8f4be1b7921f145505b6d563dc3d06ac15649118 Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Tue, 4 Jul 2023 08:23:22 +0200 Subject: [PATCH 04/14] Applied cargo fmt and clippy. --- crates/qt-build-utils/src/lib.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index 14095945a..0a9f78bb9 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -317,15 +317,15 @@ impl QtBuild { ) { println!("cargo:rustc-link-lib={link_lib}"); - match std::fs::read_to_string(&prl_path) { + match std::fs::read_to_string(prl_path) { Ok(prl) => { for line in prl.lines() { if let Some(line) = line.strip_prefix("QMAKE_PRL_LIBS = ") { parse_cflags::parse_libs_cflags( builder, name, - line.replace(r"$$[QT_INSTALL_LIBS]", &lib_path) - .replace(r"$$[QT_INSTALL_PREFIX]", &prefix_path) + line.replace(r"$$[QT_INSTALL_LIBS]", lib_path) + .replace(r"$$[QT_INSTALL_PREFIX]", prefix_path) .as_bytes(), ); } @@ -341,7 +341,13 @@ impl QtBuild { } /// Some prl files don't follow a consistent naming scheme. Try to find it by looking at all files in lib_path. - fn find_qt_module_prl(&self, lib_path: &str, prefix: &str, version_major: u32, qt_module: &str) -> String { + fn find_qt_module_prl( + &self, + lib_path: &str, + prefix: &str, + version_major: u32, + qt_module: &str, + ) -> String { match Path::new(lib_path).read_dir() { Ok(lib_dir) => { for entry in lib_dir { @@ -367,7 +373,10 @@ impl QtBuild { } } - format!("{}/{}Qt{}{}.prl",lib_path, prefix, version_major, qt_module) + format!( + "{}/{}Qt{}{}.prl", + lib_path, prefix, version_major, qt_module + ) } /// Tell Cargo to link each Qt module. From 1b753d75f6f3d67370915e1e4d0e5a69f1be32eb Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Wed, 5 Jul 2023 09:41:16 +0200 Subject: [PATCH 05/14] Applied requested builder changes --- crates/qt-build-utils/src/lib.rs | 8 ++++---- crates/qt-build-utils/src/parse_cflags.rs | 8 +++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index 0a9f78bb9..4f802d218 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -308,12 +308,12 @@ impl QtBuild { fn cargo_link_qt_library( &self, - builder: &mut cc::Build, name: &str, prefix_path: &str, lib_path: &str, link_lib: &str, prl_path: &str, + builder: &mut cc::Build, ) { println!("cargo:rustc-link-lib={link_lib}"); @@ -322,11 +322,11 @@ impl QtBuild { for line in prl.lines() { if let Some(line) = line.strip_prefix("QMAKE_PRL_LIBS = ") { parse_cflags::parse_libs_cflags( - builder, name, line.replace(r"$$[QT_INSTALL_LIBS]", lib_path) .replace(r"$$[QT_INSTALL_PREFIX]", prefix_path) .as_bytes(), + builder, ); } } @@ -422,12 +422,12 @@ impl QtBuild { }; self.cargo_link_qt_library( - builder, &format!("Qt{}{qt_module}", self.version.major), &prefix_path, &lib_path, &link_lib, &prl_path, + builder, ); } @@ -439,12 +439,12 @@ impl QtBuild { let platforms_path = format!("{}/platforms", self.qmake_query("QT_INSTALL_PLUGINS")); println!("cargo:rustc-link-search={platforms_path}"); self.cargo_link_qt_library( - builder, "qwasm", &prefix_path, &lib_path, "qwasm", &format!("{platforms_path}/libqwasm.prl"), + builder, ); } } diff --git a/crates/qt-build-utils/src/parse_cflags.rs b/crates/qt-build-utils/src/parse_cflags.rs index 7c838ee82..4ef38fb36 100644 --- a/crates/qt-build-utils/src/parse_cflags.rs +++ b/crates/qt-build-utils/src/parse_cflags.rs @@ -103,7 +103,7 @@ fn split_flags(link_args: &[u8]) -> Vec { words } -pub(crate) fn parse_libs_cflags(_builder: &mut cc::Build, name: &str, link_args: &[u8]) { +pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8], _builder: &mut cc::Build) { let mut is_msvc = false; let target = env::var("TARGET"); if let Ok(target) = &target { @@ -168,6 +168,12 @@ pub(crate) fn parse_libs_cflags(_builder: &mut cc::Build, name: &str, link_args: (path.parent(), path.file_name(), &target) { if file_name.to_string_lossy().ends_with(".o") { + // Cargo doesn't have a means to directly specify an object to link, + // so use the cc crate to specify it instead. + // TODO: pass file path directly when link-arg library type is stabilized + // https://github.com/rust-lang/rust/issues/99427#issuecomment-1562092085 + // TODO: remove builder argument when it's not used anymore to link object files. + // also remove the dependency on cc when this is done #[cfg(feature = "include_qt_objects")] _builder.object(path); } else { From db0a151aae4f203e966b8a397848e6f132a83683 Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Wed, 5 Jul 2023 09:41:57 +0200 Subject: [PATCH 06/14] Expanded documentation about fnd_qt_module --- crates/qt-build-utils/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index 4f802d218..8a5e22b94 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -341,6 +341,8 @@ impl QtBuild { } /// Some prl files don't follow a consistent naming scheme. Try to find it by looking at all files in lib_path. + /// The android libraries adds its architecture at the end of it prl files eg liQt6Core_{arch}.prl. + /// The arch placeholder is somewhat different for each architecture preventing the use of a simple format. fn find_qt_module_prl( &self, lib_path: &str, From f497c91942b90e86e0572a0e45066ffed49e9fb4 Mon Sep 17 00:00:00 2001 From: Be Wilson Date: Wed, 5 Jul 2023 16:29:30 -0500 Subject: [PATCH 07/14] deduplicate linked .o files --- crates/cxx-qt-build/Cargo.toml | 1 - crates/qt-build-utils/src/parse_cflags.rs | 33 ++++++++++++++--------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/crates/cxx-qt-build/Cargo.toml b/crates/cxx-qt-build/Cargo.toml index 5c5cdf238..cfa20e682 100644 --- a/crates/cxx-qt-build/Cargo.toml +++ b/crates/cxx-qt-build/Cargo.toml @@ -28,4 +28,3 @@ version_check = "0.9" default = ["qt_gui", "qt_qml"] qt_gui = ["cxx-qt-lib-headers/qt_gui"] qt_qml = ["cxx-qt-lib-headers/qt_qml"] -include_qt_objects = ["qt-build-utils/include_qt_objects"] diff --git a/crates/qt-build-utils/src/parse_cflags.rs b/crates/qt-build-utils/src/parse_cflags.rs index 4ef38fb36..0a5fbbcd6 100644 --- a/crates/qt-build-utils/src/parse_cflags.rs +++ b/crates/qt-build-utils/src/parse_cflags.rs @@ -8,7 +8,9 @@ //! It has been decoupled from the pkg-config crate because qt-build-utils reads Qt's .prl files instead, which //! does not require a pkg-config executable to be available. -use std::env; +use std::{collections::HashSet, env, sync::OnceLock}; + +static mut LINKED_OBJECT_FILES: OnceLock> = OnceLock::new(); /// Extract the &str to pass to cargo:rustc-link-lib from a filename (just the file name, not including directories) /// using target-specific logic. @@ -103,7 +105,7 @@ fn split_flags(link_args: &[u8]) -> Vec { words } -pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8], _builder: &mut cc::Build) { +pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8], builder: &mut cc::Build) { let mut is_msvc = false; let target = env::var("TARGET"); if let Ok(target) = &target { @@ -162,20 +164,27 @@ pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8], _builder: &mut cc: if path.is_file() { // Cargo doesn't have a means to directly specify a file path to link, // so split up the path into the parent directory and library name. - // TODO: pass file path directly when link-arg library type is stabilized - // https://github.com/rust-lang/rust/issues/99427 if let (Some(dir), Some(file_name), Ok(target)) = (path.parent(), path.file_name(), &target) { if file_name.to_string_lossy().ends_with(".o") { - // Cargo doesn't have a means to directly specify an object to link, - // so use the cc crate to specify it instead. - // TODO: pass file path directly when link-arg library type is stabilized - // https://github.com/rust-lang/rust/issues/99427#issuecomment-1562092085 - // TODO: remove builder argument when it's not used anymore to link object files. - // also remove the dependency on cc when this is done - #[cfg(feature = "include_qt_objects")] - _builder.object(path); + let path_string = path.to_string_lossy().to_string(); + unsafe { + // Linking will fail with duplicate symbol errors if the same .o file is linked twice. + // Many of Qt's .prl files repeat listing .o files that other .prl files also list. + let already_linked_object_files = + LINKED_OBJECT_FILES.get_or_init(|| HashSet::new()); + if !already_linked_object_files.contains(&path_string) { + // Cargo doesn't have a means to directly specify an object to link, + // so use the cc crate to specify it instead. + // TODO: pass file path directly when link-arg library type is stabilized + // https://github.com/rust-lang/rust/issues/99427#issuecomment-1562092085 + // TODO: remove builder argument when it's not used anymore to link object files. + // also remove the dependency on cc when this is done + builder.object(path); + } + LINKED_OBJECT_FILES.get_mut().unwrap().insert(path_string); + } } else { match extract_lib_from_filename(target, &file_name.to_string_lossy()) { Some(lib_basename) => { From 8a055837ddf6d70ca974d5450e45df5797ffc185 Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Sat, 8 Jul 2023 21:10:09 +0200 Subject: [PATCH 08/14] cargo_link_libraries is invoked by two crates cxx-qt and cxx-qt-build. when static linking only one of them is allowed to to add object files else duplicate symbol errors will be produced. --- crates/cxx-qt-build/src/lib.rs | 2 +- crates/cxx-qt-lib/build.rs | 2 +- crates/qt-build-utils/Cargo.toml | 3 -- crates/qt-build-utils/src/lib.rs | 8 ++--- crates/qt-build-utils/src/parse_cflags.rs | 38 +++++++++++++---------- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index 013903a80..754975c4f 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -399,7 +399,7 @@ impl CxxQtBuilder { let mut qtbuild = qt_build_utils::QtBuild::new(self.qt_modules.into_iter().collect()) .expect("Could not find Qt installation"); - qtbuild.cargo_link_libraries(&mut self.cc_builder); + qtbuild.cargo_link_libraries(Some(&mut self.cc_builder)); // Write cxx-qt-gen, cxx-qt-lib and cxx headers cxx_qt_gen::write_headers(format!("{header_root}/cxx-qt-common")); diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index 04a63415e..1e9f25332 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -182,7 +182,7 @@ fn main() { let mut builder = cxx_build::bridges(rust_bridges.iter().map(|bridge| format!("src/{bridge}.rs"))); - qtbuild.cargo_link_libraries(&mut builder); + qtbuild.cargo_link_libraries(None); // Required for tests qt_build_utils::setup_linker(); diff --git a/crates/qt-build-utils/Cargo.toml b/crates/qt-build-utils/Cargo.toml index 437ad09c5..6c6a830d8 100644 --- a/crates/qt-build-utils/Cargo.toml +++ b/crates/qt-build-utils/Cargo.toml @@ -16,6 +16,3 @@ repository.workspace = true cc = "1.0.74" versions = "4.1.0" thiserror = "1.0" - -[features] -include_qt_objects = [] diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index 8a5e22b94..731ed9fd2 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -313,7 +313,7 @@ impl QtBuild { lib_path: &str, link_lib: &str, prl_path: &str, - builder: &mut cc::Build, + builder: &mut Option<&mut cc::Build>, ) { println!("cargo:rustc-link-lib={link_lib}"); @@ -382,7 +382,7 @@ impl QtBuild { } /// Tell Cargo to link each Qt module. - pub fn cargo_link_libraries(&self, builder: &mut cc::Build) { + pub fn cargo_link_libraries(&self, mut builder: Option<&mut cc::Build>) { let prefix_path = self.qmake_query("QT_INSTALL_PREFIX"); let lib_path = self.qmake_query("QT_INSTALL_LIBS"); println!("cargo:rustc-link-search={lib_path}"); @@ -429,7 +429,7 @@ impl QtBuild { &lib_path, &link_lib, &prl_path, - builder, + &mut builder, ); } @@ -446,7 +446,7 @@ impl QtBuild { &lib_path, "qwasm", &format!("{platforms_path}/libqwasm.prl"), - builder, + &mut builder, ); } } diff --git a/crates/qt-build-utils/src/parse_cflags.rs b/crates/qt-build-utils/src/parse_cflags.rs index 0a5fbbcd6..00ff62596 100644 --- a/crates/qt-build-utils/src/parse_cflags.rs +++ b/crates/qt-build-utils/src/parse_cflags.rs @@ -105,7 +105,11 @@ fn split_flags(link_args: &[u8]) -> Vec { words } -pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8], builder: &mut cc::Build) { +pub(crate) fn parse_libs_cflags( + name: &str, + link_args: &[u8], + builder: &mut Option<&mut cc::Build>, +) { let mut is_msvc = false; let target = env::var("TARGET"); if let Ok(target) = &target { @@ -168,22 +172,24 @@ pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8], builder: &mut cc:: (path.parent(), path.file_name(), &target) { if file_name.to_string_lossy().ends_with(".o") { - let path_string = path.to_string_lossy().to_string(); - unsafe { - // Linking will fail with duplicate symbol errors if the same .o file is linked twice. - // Many of Qt's .prl files repeat listing .o files that other .prl files also list. - let already_linked_object_files = - LINKED_OBJECT_FILES.get_or_init(|| HashSet::new()); - if !already_linked_object_files.contains(&path_string) { - // Cargo doesn't have a means to directly specify an object to link, - // so use the cc crate to specify it instead. - // TODO: pass file path directly when link-arg library type is stabilized - // https://github.com/rust-lang/rust/issues/99427#issuecomment-1562092085 - // TODO: remove builder argument when it's not used anymore to link object files. - // also remove the dependency on cc when this is done - builder.object(path); + if let Some(builder) = builder { + let path_string = path.to_string_lossy().to_string(); + unsafe { + // Linking will fail with duplicate symbol errors if the same .o file is linked twice. + // Many of Qt's .prl files repeat listing .o files that other .prl files also list. + let already_linked_object_files = + LINKED_OBJECT_FILES.get_or_init(HashSet::new); + if !already_linked_object_files.contains(&path_string) { + // Cargo doesn't have a means to directly specify an object to link, + // so use the cc crate to specify it instead. + // TODO: pass file path directly when link-arg library type is stabilized + // https://github.com/rust-lang/rust/issues/99427#issuecomment-1562092085 + // TODO: remove builder argument when it's not used anymore to link object files. + // also remove the dependency on cc when this is done + builder.object(path); + } + LINKED_OBJECT_FILES.get_mut().unwrap().insert(path_string); } - LINKED_OBJECT_FILES.get_mut().unwrap().insert(path_string); } } else { match extract_lib_from_filename(target, &file_name.to_string_lossy()) { From 7bd5f06d133e94783660d68090108644eb36bb2e Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Sat, 8 Jul 2023 21:10:55 +0200 Subject: [PATCH 09/14] some external build systems will include object files found by cargo_link_libraries and are hard to remove. instead instruct this function to not include these object files. --- crates/cxx-qt-build/Cargo.toml | 1 + crates/cxx-qt-build/src/lib.rs | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/cxx-qt-build/Cargo.toml b/crates/cxx-qt-build/Cargo.toml index cfa20e682..9528b0863 100644 --- a/crates/cxx-qt-build/Cargo.toml +++ b/crates/cxx-qt-build/Cargo.toml @@ -28,3 +28,4 @@ version_check = "0.9" default = ["qt_gui", "qt_qml"] qt_gui = ["cxx-qt-lib-headers/qt_gui"] qt_qml = ["cxx-qt-lib-headers/qt_qml"] +link_qt_external = [] diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index 754975c4f..f9a66e93d 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -399,7 +399,13 @@ impl CxxQtBuilder { let mut qtbuild = qt_build_utils::QtBuild::new(self.qt_modules.into_iter().collect()) .expect("Could not find Qt installation"); - qtbuild.cargo_link_libraries(Some(&mut self.cc_builder)); + // some external build systems will include object files found by cargo_link_libraries and + // are hard to remove. instead instruct this function to not include these object files. + if cfg!(feature = "link_qt_external") { + qtbuild.cargo_link_libraries(None); + } else { + qtbuild.cargo_link_libraries(Some(&mut self.cc_builder)); + } // Write cxx-qt-gen, cxx-qt-lib and cxx headers cxx_qt_gen::write_headers(format!("{header_root}/cxx-qt-common")); From 356f762c519e2114f553244370f7708cbc16be8f Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Sat, 8 Jul 2023 21:37:18 +0200 Subject: [PATCH 10/14] Fixed some assumptions with prl file searching by hardcoding android architectures. --- crates/qt-build-utils/src/lib.rs | 40 ++++++++++++++------------------ 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index 731ed9fd2..59bc97385 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -340,9 +340,8 @@ impl QtBuild { } } - /// Some prl files don't follow a consistent naming scheme. Try to find it by looking at all files in lib_path. - /// The android libraries adds its architecture at the end of it prl files eg liQt6Core_{arch}.prl. - /// The arch placeholder is somewhat different for each architecture preventing the use of a simple format. + /// Some prl files include their architecture in their naming scheme. + /// Just try all known architectures and fallback to non when they all failed. fn find_qt_module_prl( &self, lib_path: &str, @@ -350,28 +349,23 @@ impl QtBuild { version_major: u32, qt_module: &str, ) -> String { - match Path::new(lib_path).read_dir() { - Ok(lib_dir) => { - for entry in lib_dir { - match entry { - Ok(entry) => { - let file_name = entry.file_name(); - let file_name = file_name.to_string_lossy(); - let prl_file = file_name.ends_with(".prl"); - let matches_module = file_name - .contains(&format!("Qt{}{}", self.version.major, qt_module)); - if prl_file && matches_module { - return entry.path().display().to_string(); - } - } - Err(e) => { - println!("cargo:warning=Could not read {} entry: {}", lib_path, e); - } + for arch in ["", "_arm64-v8a", "_armeabi-v7a", "_x86", "_x86_64"] { + let prl_path = format!( + "{}/{}Qt{}{}{}.prl", + lib_path, prefix, version_major, qt_module, arch + ); + match Path::new(&prl_path).try_exists() { + Ok(exists) => { + if exists { + return prl_path; } } - } - Err(e) => { - println!("cargo:warning=Could not read dir {}: {}", lib_path, e); + Err(e) => { + println!( + "cargo:warning=failed checking for existence of {}: {}", + prl_path, e + ); + } } } From 3650853337cab767ae9ca3db75929582aad71e04 Mon Sep 17 00:00:00 2001 From: Jimmy van Hest Date: Sat, 8 Jul 2023 21:57:36 +0200 Subject: [PATCH 11/14] Reverted unnecessary changes. --- crates/cxx-qt-lib/build.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index 1e9f25332..253818b40 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -19,6 +19,18 @@ fn main() { qt_modules.push("Qml".to_owned()); } + let qtbuild = qt_build_utils::QtBuild::new(qt_modules).expect("Could not find Qt installation"); + qtbuild.cargo_link_libraries(None); + // Required for tests + qt_build_utils::setup_linker(); + + // Find the Qt version and tell the Rust compiler + // this allows us to have conditional Rust code + println!( + "cargo:rustc-cfg=qt_version_major=\"{}\"", + qtbuild.version().major + ); + let mut rust_bridges = vec![ "core/qbytearray", "core/qcoreapplication", @@ -171,8 +183,6 @@ fn main() { println!("cargo:rerun-if-changed=src/{bridge}.rs"); } - let qtbuild = qt_build_utils::QtBuild::new(qt_modules).expect("Could not find Qt installation"); - for include_path in qtbuild.include_paths() { cxx_build::CFG .exported_header_dirs @@ -182,17 +192,6 @@ fn main() { let mut builder = cxx_build::bridges(rust_bridges.iter().map(|bridge| format!("src/{bridge}.rs"))); - qtbuild.cargo_link_libraries(None); - // Required for tests - qt_build_utils::setup_linker(); - - // Find the Qt version and tell the Rust compiler - // this allows us to have conditional Rust code - println!( - "cargo:rustc-cfg=qt_version_major=\"{}\"", - qtbuild.version().major - ); - let mut cpp_files = vec![ "core/qbytearray", "core/qcoreapplication", From 3c780797024a3b61bf069a4d8b305bdabdb707b4 Mon Sep 17 00:00:00 2001 From: Be Wilson Date: Mon, 10 Jul 2023 17:23:25 -0500 Subject: [PATCH 12/14] cxx-qt-build: add Cargo feature to toggle linking Qt's .o files Unfortunately, there is no way to get linking to work in every case without conditional compilation. This feature needs to be enabled for bin crates or when running `cargo test` for library crates. The feature must not be enabled when builing a staticlib then linking it with CMake because CMake will also link the .o files, which makes linking fail with duplicate symbol errors. --- CMakeLists.txt | 4 ++-- crates/cxx-qt-build/Cargo.toml | 1 + crates/qt-build-utils/Cargo.toml | 13 +++++++++++++ crates/qt-build-utils/src/parse_cflags.rs | 16 +++++++++++----- examples/cargo_without_cmake/Cargo.toml | 3 ++- examples/demo_threading/rust/Cargo.toml | 3 +++ .../qml_extension_plugin/plugin/rust/Cargo.toml | 3 +++ examples/qml_features/rust/Cargo.toml | 3 +++ examples/qml_minimal/rust/Cargo.toml | 4 ++++ 9 files changed, 42 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46c08a491..58632b7d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,9 +195,9 @@ endif() set(CARGO_TARGET_DIR "${CMAKE_BINARY_DIR}/${BUILD_DIR}/cargo/build") # Add CMake tests for `cargo test/clippy/fmt/doc`. -add_test(NAME cargo_tests COMMAND cargo test --all-targets --target-dir +add_test(NAME cargo_tests COMMAND cargo test --features link_qt_object_files --all-targets --target-dir ${CARGO_TARGET_DIR}) -add_test(NAME cargo_doc_tests COMMAND cargo test --doc --target-dir +add_test(NAME cargo_doc_tests COMMAND cargo test --features link_qt_object_files --doc --target-dir ${CARGO_TARGET_DIR}) add_test(NAME cargo_doc COMMAND cargo doc --workspace --target-dir ${CARGO_TARGET_DIR}) add_test(NAME cargo_clippy COMMAND cargo clippy --all-targets --target-dir diff --git a/crates/cxx-qt-build/Cargo.toml b/crates/cxx-qt-build/Cargo.toml index 9528b0863..ead6c6108 100644 --- a/crates/cxx-qt-build/Cargo.toml +++ b/crates/cxx-qt-build/Cargo.toml @@ -29,3 +29,4 @@ default = ["qt_gui", "qt_qml"] qt_gui = ["cxx-qt-lib-headers/qt_gui"] qt_qml = ["cxx-qt-lib-headers/qt_qml"] link_qt_external = [] +link_qt_object_files = ["qt-build-utils/link_qt_object_files"] diff --git a/crates/qt-build-utils/Cargo.toml b/crates/qt-build-utils/Cargo.toml index 6c6a830d8..91e964631 100644 --- a/crates/qt-build-utils/Cargo.toml +++ b/crates/qt-build-utils/Cargo.toml @@ -16,3 +16,16 @@ repository.workspace = true cc = "1.0.74" versions = "4.1.0" thiserror = "1.0" + +[features] +# When Cargo links an executable, whether a bin crate or test executable, +# and Qt 6 is linked statically, this feature must be enabled to link +# unarchived .o files with static symbols that Qt ships (for example +# to initialize Qt resources embedded within Qt libraries). +# +# CMake also links those .o files when linking Qt's targets, so this +# feature must be disabled for staticlib crates. Otherwise, linking +# will fail with duplicate symbol errors. +# +# When linking Qt dynamically, this makes no difference. +link_qt_object_files = [] diff --git a/crates/qt-build-utils/src/parse_cflags.rs b/crates/qt-build-utils/src/parse_cflags.rs index 00ff62596..820e6ac42 100644 --- a/crates/qt-build-utils/src/parse_cflags.rs +++ b/crates/qt-build-utils/src/parse_cflags.rs @@ -8,8 +8,12 @@ //! It has been decoupled from the pkg-config crate because qt-build-utils reads Qt's .prl files instead, which //! does not require a pkg-config executable to be available. -use std::{collections::HashSet, env, sync::OnceLock}; +use std::env; +#[cfg(feature = "link_qt_object_files")] +use std::{collections::HashSet, sync::OnceLock}; + +#[cfg(feature = "link_qt_object_files")] static mut LINKED_OBJECT_FILES: OnceLock> = OnceLock::new(); /// Extract the &str to pass to cargo:rustc-link-lib from a filename (just the file name, not including directories) @@ -108,7 +112,7 @@ fn split_flags(link_args: &[u8]) -> Vec { pub(crate) fn parse_libs_cflags( name: &str, link_args: &[u8], - builder: &mut Option<&mut cc::Build>, + _builder: &mut Option<&mut cc::Build>, ) { let mut is_msvc = false; let target = env::var("TARGET"); @@ -171,8 +175,10 @@ pub(crate) fn parse_libs_cflags( if let (Some(dir), Some(file_name), Ok(target)) = (path.parent(), path.file_name(), &target) { - if file_name.to_string_lossy().ends_with(".o") { - if let Some(builder) = builder { + let file_name = file_name.to_string_lossy(); + if file_name.ends_with(".o") { + #[cfg(feature = "link_qt_object_files")] + if let Some(builder) = _builder { let path_string = path.to_string_lossy().to_string(); unsafe { // Linking will fail with duplicate symbol errors if the same .o file is linked twice. @@ -192,7 +198,7 @@ pub(crate) fn parse_libs_cflags( } } } else { - match extract_lib_from_filename(target, &file_name.to_string_lossy()) { + match extract_lib_from_filename(target, &file_name) { Some(lib_basename) => { println!("cargo:rustc-link-search={}", dir.display()); println!("cargo:rustc-link-lib={lib_basename}"); diff --git a/examples/cargo_without_cmake/Cargo.toml b/examples/cargo_without_cmake/Cargo.toml index 33a3356f1..5ee971bb8 100644 --- a/examples/cargo_without_cmake/Cargo.toml +++ b/examples/cargo_without_cmake/Cargo.toml @@ -27,5 +27,6 @@ cxx-qt-lib.workspace = true [build-dependencies] # Use `cxx-qt-build = "0.5"` here instead! -cxx-qt-build.workspace = true +# The link_qt_object_files feature is required for statically linking Qt 6. +cxx-qt-build = { workspace = true, features = [ "link_qt_object_files" ] } # ANCHOR_END: book_cargo_toml_no_cmake diff --git a/examples/demo_threading/rust/Cargo.toml b/examples/demo_threading/rust/Cargo.toml index d2a16d2a3..6bc339a2c 100644 --- a/examples/demo_threading/rust/Cargo.toml +++ b/examples/demo_threading/rust/Cargo.toml @@ -25,3 +25,6 @@ uuid = { version = "1.2", features = ["serde", "v4"] } [build-dependencies] cxx-qt-build.workspace = true + +[features] +link_qt_object_files = [ "cxx-qt-build/link_qt_object_files" ] diff --git a/examples/qml_extension_plugin/plugin/rust/Cargo.toml b/examples/qml_extension_plugin/plugin/rust/Cargo.toml index 7f3a82dee..2bb281d60 100644 --- a/examples/qml_extension_plugin/plugin/rust/Cargo.toml +++ b/examples/qml_extension_plugin/plugin/rust/Cargo.toml @@ -22,3 +22,6 @@ serde_json.workspace = true [build-dependencies] cxx-qt-build.workspace = true + +[features] +link_qt_object_files = [ "cxx-qt-build/link_qt_object_files" ] diff --git a/examples/qml_features/rust/Cargo.toml b/examples/qml_features/rust/Cargo.toml index 7282ec160..62a0c5f46 100644 --- a/examples/qml_features/rust/Cargo.toml +++ b/examples/qml_features/rust/Cargo.toml @@ -22,3 +22,6 @@ serde_json.workspace = true [build-dependencies] cxx-qt-build.workspace = true + +[features] +link_qt_object_files = [ "cxx-qt-build/link_qt_object_files" ] diff --git a/examples/qml_minimal/rust/Cargo.toml b/examples/qml_minimal/rust/Cargo.toml index 5be6184ba..008ebfa91 100644 --- a/examples/qml_minimal/rust/Cargo.toml +++ b/examples/qml_minimal/rust/Cargo.toml @@ -38,6 +38,10 @@ cxx-qt-lib.workspace = true [build-dependencies] # Use `cxx-qt-build = "0.5"` here instead! cxx-qt-build.workspace = true + +[features] +# This feature must be enabled for `cargo test` when linking Qt 6 statically. +link_qt_object_files = [ "cxx-qt-build/link_qt_object_files" ] # ANCHOR_END: book_build_dependencies # ANCHOR_END: book_all From d0bab9c99c2b6a36f0499d0cdf143e6c4f5125c7 Mon Sep 17 00:00:00 2001 From: Be Wilson Date: Mon, 10 Jul 2023 18:02:39 -0500 Subject: [PATCH 13/14] cxx-qt-build: remove unused link_qt_external feature --- crates/cxx-qt-build/Cargo.toml | 1 - crates/cxx-qt-build/src/lib.rs | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/crates/cxx-qt-build/Cargo.toml b/crates/cxx-qt-build/Cargo.toml index ead6c6108..d26fbdb2b 100644 --- a/crates/cxx-qt-build/Cargo.toml +++ b/crates/cxx-qt-build/Cargo.toml @@ -28,5 +28,4 @@ version_check = "0.9" default = ["qt_gui", "qt_qml"] qt_gui = ["cxx-qt-lib-headers/qt_gui"] qt_qml = ["cxx-qt-lib-headers/qt_qml"] -link_qt_external = [] link_qt_object_files = ["qt-build-utils/link_qt_object_files"] diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index f9a66e93d..754975c4f 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -399,13 +399,7 @@ impl CxxQtBuilder { let mut qtbuild = qt_build_utils::QtBuild::new(self.qt_modules.into_iter().collect()) .expect("Could not find Qt installation"); - // some external build systems will include object files found by cargo_link_libraries and - // are hard to remove. instead instruct this function to not include these object files. - if cfg!(feature = "link_qt_external") { - qtbuild.cargo_link_libraries(None); - } else { - qtbuild.cargo_link_libraries(Some(&mut self.cc_builder)); - } + qtbuild.cargo_link_libraries(Some(&mut self.cc_builder)); // Write cxx-qt-gen, cxx-qt-lib and cxx headers cxx_qt_gen::write_headers(format!("{header_root}/cxx-qt-common")); From 78155080ae401b8e4afc05ab3358a308f105d40e Mon Sep 17 00:00:00 2001 From: Be Wilson Date: Tue, 11 Jul 2023 11:13:22 -0500 Subject: [PATCH 14/14] qt-build-utils: use cc::Build insteaed of Option Whether to link the .o files is now controlled by a Cargo option, not the calling code. --- crates/cxx-qt-build/src/lib.rs | 2 +- crates/cxx-qt-lib/Cargo.toml | 1 + crates/cxx-qt-lib/build.rs | 4 +++- crates/qt-build-utils/src/lib.rs | 8 ++++---- crates/qt-build-utils/src/parse_cflags.rs | 10 +++------- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index 754975c4f..013903a80 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -399,7 +399,7 @@ impl CxxQtBuilder { let mut qtbuild = qt_build_utils::QtBuild::new(self.qt_modules.into_iter().collect()) .expect("Could not find Qt installation"); - qtbuild.cargo_link_libraries(Some(&mut self.cc_builder)); + qtbuild.cargo_link_libraries(&mut self.cc_builder); // Write cxx-qt-gen, cxx-qt-lib and cxx headers cxx_qt_gen::write_headers(format!("{header_root}/cxx-qt-common")); diff --git a/crates/cxx-qt-lib/Cargo.toml b/crates/cxx-qt-lib/Cargo.toml index 5387dadfc..5a3651980 100644 --- a/crates/cxx-qt-lib/Cargo.toml +++ b/crates/cxx-qt-lib/Cargo.toml @@ -40,3 +40,4 @@ qt_gui = ["cxx-qt-lib-headers/qt_gui"] qt_qml = ["cxx-qt-lib-headers/qt_qml"] time = ["dep:time"] url = ["dep:url"] +link_qt_object_files = ["qt-build-utils/link_qt_object_files"] diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index 253818b40..1234c912d 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -20,7 +20,7 @@ fn main() { } let qtbuild = qt_build_utils::QtBuild::new(qt_modules).expect("Could not find Qt installation"); - qtbuild.cargo_link_libraries(None); + // Required for tests qt_build_utils::setup_linker(); @@ -192,6 +192,8 @@ fn main() { let mut builder = cxx_build::bridges(rust_bridges.iter().map(|bridge| format!("src/{bridge}.rs"))); + qtbuild.cargo_link_libraries(&mut builder); + let mut cpp_files = vec![ "core/qbytearray", "core/qcoreapplication", diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs index 59bc97385..aab95a0f8 100644 --- a/crates/qt-build-utils/src/lib.rs +++ b/crates/qt-build-utils/src/lib.rs @@ -313,7 +313,7 @@ impl QtBuild { lib_path: &str, link_lib: &str, prl_path: &str, - builder: &mut Option<&mut cc::Build>, + builder: &mut cc::Build, ) { println!("cargo:rustc-link-lib={link_lib}"); @@ -376,7 +376,7 @@ impl QtBuild { } /// Tell Cargo to link each Qt module. - pub fn cargo_link_libraries(&self, mut builder: Option<&mut cc::Build>) { + pub fn cargo_link_libraries(&self, builder: &mut cc::Build) { let prefix_path = self.qmake_query("QT_INSTALL_PREFIX"); let lib_path = self.qmake_query("QT_INSTALL_LIBS"); println!("cargo:rustc-link-search={lib_path}"); @@ -423,7 +423,7 @@ impl QtBuild { &lib_path, &link_lib, &prl_path, - &mut builder, + builder, ); } @@ -440,7 +440,7 @@ impl QtBuild { &lib_path, "qwasm", &format!("{platforms_path}/libqwasm.prl"), - &mut builder, + builder, ); } } diff --git a/crates/qt-build-utils/src/parse_cflags.rs b/crates/qt-build-utils/src/parse_cflags.rs index 820e6ac42..cbb01b565 100644 --- a/crates/qt-build-utils/src/parse_cflags.rs +++ b/crates/qt-build-utils/src/parse_cflags.rs @@ -109,11 +109,7 @@ fn split_flags(link_args: &[u8]) -> Vec { words } -pub(crate) fn parse_libs_cflags( - name: &str, - link_args: &[u8], - _builder: &mut Option<&mut cc::Build>, -) { +pub(crate) fn parse_libs_cflags(name: &str, link_args: &[u8], _builder: &mut cc::Build) { let mut is_msvc = false; let target = env::var("TARGET"); if let Ok(target) = &target { @@ -178,7 +174,7 @@ pub(crate) fn parse_libs_cflags( let file_name = file_name.to_string_lossy(); if file_name.ends_with(".o") { #[cfg(feature = "link_qt_object_files")] - if let Some(builder) = _builder { + { let path_string = path.to_string_lossy().to_string(); unsafe { // Linking will fail with duplicate symbol errors if the same .o file is linked twice. @@ -192,7 +188,7 @@ pub(crate) fn parse_libs_cflags( // https://github.com/rust-lang/rust/issues/99427#issuecomment-1562092085 // TODO: remove builder argument when it's not used anymore to link object files. // also remove the dependency on cc when this is done - builder.object(path); + _builder.object(path); } LINKED_OBJECT_FILES.get_mut().unwrap().insert(path_string); }