Skip to content

Commit

Permalink
cxx-qt-lib: use +whole_archive for std_types so that cargo-only works
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ahayzen-kdab committed Jun 26, 2023
1 parent 0b17899 commit 723df93
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
1 change: 1 addition & 0 deletions crates/cxx-qt-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 32 additions & 7 deletions crates/cxx-qt-lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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");
}

0 comments on commit 723df93

Please sign in to comment.