Skip to content

Commit 3672533

Browse files
committed
cxx-qt-lib: use +whole_archive for std_types so that cargo-only works
When building with cargo we need to ensure that the statics aren't optimised out for registering types with Qt 5. Otherwise we cannot use numbers in QML. Closes #592
1 parent f76a089 commit 3672533

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ impl CxxQtBuilder {
429429
// https://github.com/rust-lang/rust/issues/110912
430430
cc_builder_whole_archive.link_lib_modifier("-bundle");
431431
for builder in [&mut self.cc_builder, &mut cc_builder_whole_archive] {
432+
// Note, ensure our settings stay in sync across cxx-qt-build and cxx-qt-lib
432433
builder.cpp(true);
433434
// MSVC
434435
builder.flag_if_supported("/std:c++17");

crates/cxx-qt-lib/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ time = { version = "0.3.20", optional = true }
2626
url = { version = "2.3", optional = true }
2727

2828
[build-dependencies]
29+
cc.workspace = true
2930
cxx-build.workspace = true
3031
cxx-qt-lib-headers.workspace = true
3132
qt-build-utils.workspace = true

crates/cxx-qt-lib/build.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,27 @@ fn main() {
232232
}
233233
builder.file("src/qt_types.cpp");
234234
println!("cargo:rerun-if-changed=src/qt_types.cpp");
235-
builder.file("src/std_types.cpp");
236-
println!("cargo:rerun-if-changed=src/std_types.cpp");
237235
println!("cargo:rerun-if-changed=src/assertion_utils.h");
238236

237+
// Setup compiler
238+
// qRegisterMetaType needs to be linked with +whole-archive
239+
// because they use static variables which need to be initialized before main
240+
// (regardless of whether main is in Rust or C++). Normally linkers only copy symbols referenced
241+
// from within main when static linking, which would result in discarding those static variables.
242+
// Use a separate cc::Build for the little amount of code that needs to be linked with +whole-archive
243+
// to avoid bloating the binary.
244+
let mut cc_builder_whole_archive = cc::Build::new();
245+
cc_builder_whole_archive.link_lib_modifier("+whole-archive");
246+
// Workaround for spurious compiler error in Rust 1.69. The bug has been fixed, but keeping this
247+
// workaround seems to be harmless.
248+
// https://github.com/rust-lang/rust/issues/110912
249+
cc_builder_whole_archive.link_lib_modifier("-bundle");
250+
for include_path in qtbuild.include_paths() {
251+
cc_builder_whole_archive.include(include_path);
252+
}
253+
cc_builder_whole_archive.file("src/std_types.cpp");
254+
println!("cargo:rerun-if-changed=src/std_types.cpp");
255+
239256
// Write this library's manually written C++ headers to files and add them to include paths
240257
let out_dir = std::env::var("OUT_DIR").unwrap();
241258
cxx_qt_lib_headers::write_headers(format!("{out_dir}/cxx-qt-lib"));
@@ -251,11 +268,17 @@ fn main() {
251268
builder.define("CXX_QT_QML_FEATURE", None);
252269
}
253270

254-
// MSVC
255-
builder.flag_if_supported("/std:c++17");
256-
builder.flag_if_supported("/Zc:__cplusplus");
257-
builder.flag_if_supported("/permissive-");
258-
// GCC + Clang
259-
builder.flag_if_supported("-std=c++17");
271+
for builder in [&mut builder, &mut cc_builder_whole_archive] {
272+
// Note, ensure our settings stay in sync across cxx-qt-build and cxx-qt-lib
273+
builder.cpp(true);
274+
// MSVC
275+
builder.flag_if_supported("/std:c++17");
276+
builder.flag_if_supported("/Zc:__cplusplus");
277+
builder.flag_if_supported("/permissive-");
278+
// GCC + Clang
279+
builder.flag_if_supported("-std=c++17");
280+
}
281+
282+
cc_builder_whole_archive.compile("cxx-qt-lib-static-initializers");
260283
builder.compile("cxx-qt-lib");
261284
}

0 commit comments

Comments
 (0)