diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index e7db5fb51..af92b34cb 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -429,6 +429,7 @@ impl CxxQtBuilder { // https://github.com/rust-lang/rust/issues/110912 cc_builder_whole_archive.link_lib_modifier("-bundle"); for builder in [&mut self.cc_builder, &mut cc_builder_whole_archive] { + // Note, ensure our settings stay in sync across cxx-qt-build and cxx-qt-lib builder.cpp(true); // MSVC builder.flag_if_supported("/std:c++17"); diff --git a/crates/cxx-qt-lib/Cargo.toml b/crates/cxx-qt-lib/Cargo.toml index 5387dadfc..1f4b73921 100644 --- a/crates/cxx-qt-lib/Cargo.toml +++ b/crates/cxx-qt-lib/Cargo.toml @@ -26,6 +26,7 @@ time = { version = "0.3.20", optional = true } url = { version = "2.3", optional = true } [build-dependencies] +cc.workspace = true cxx-build.workspace = true cxx-qt-lib-headers.workspace = true qt-build-utils.workspace = true diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index 8c432f4cf..f460b1f87 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -232,9 +232,28 @@ fn main() { } builder.file("src/qt_types.cpp"); println!("cargo:rerun-if-changed=src/qt_types.cpp"); + println!("cargo:rerun-if-changed=src/assertion_utils.h"); + + // Setup compiler + // qRegisterMetaType needs to be linked with +whole-archive + // because they use static variables which need to be initialized before main + // (regardless of whether main is in Rust or C++). Normally linkers only copy symbols referenced + // from within main when static linking, which would result in discarding those static variables. + // Use a separate cc::Build for the little amount of code that needs to be linked with +whole-archive + // to avoid bloating the binary. + let mut cc_builder_whole_archive = cc::Build::new(); + cc_builder_whole_archive.link_lib_modifier("+whole-archive"); + // Workaround for spurious compiler error in Rust 1.69. The bug has been fixed, but keeping this + // workaround seems to be harmless. + // https://github.com/rust-lang/rust/issues/110912 + cc_builder_whole_archive.link_lib_modifier("-bundle"); + for include_path in qtbuild.include_paths() { + cc_builder_whole_archive.include(include_path); + } + cc_builder_whole_archive.file("src/std_types.cpp"); + // Still expose std_types.cpp to the builder so that CMake builds work builder.file("src/std_types.cpp"); println!("cargo:rerun-if-changed=src/std_types.cpp"); - println!("cargo:rerun-if-changed=src/assertion_utils.h"); // Write this library's manually written C++ headers to files and add them to include paths let out_dir = std::env::var("OUT_DIR").unwrap(); @@ -251,11 +270,17 @@ fn main() { builder.define("CXX_QT_QML_FEATURE", None); } - // MSVC - builder.flag_if_supported("/std:c++17"); - builder.flag_if_supported("/Zc:__cplusplus"); - builder.flag_if_supported("/permissive-"); - // GCC + Clang - builder.flag_if_supported("-std=c++17"); + for builder in [&mut builder, &mut cc_builder_whole_archive] { + // Note, ensure our settings stay in sync across cxx-qt-build and cxx-qt-lib + builder.cpp(true); + // MSVC + builder.flag_if_supported("/std:c++17"); + builder.flag_if_supported("/Zc:__cplusplus"); + builder.flag_if_supported("/permissive-"); + // GCC + Clang + builder.flag_if_supported("-std=c++17"); + } + + cc_builder_whole_archive.compile("cxx-qt-lib-static-initializers"); builder.compile("cxx-qt-lib"); }