Description
Code
I tried this code in a library used in build.rs
// Static QML plugin and Qt resource initialization need 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");
...
// cc::Build::file and cc::Build::compile are called on cc_builder_whole_archive later
In Cargo.toml:
[lib]
crate-type = ["staticlib"]
I expected to see this happen: build succeeds, but +whole-archive
effectively does nothing because the final link of the executable is done by an external build system (CMake in this case)
Instead, this happened: build fails with
error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
Version it worked on
It most recently worked on: 1.68
Version with regression
1.69.0
Backtrace
N/A
Workaround
Add -bundle
link modifier:
cc_builder_whole_archive.link_lib_modifier("-bundle");
Neither +bundle nor -bundle seem to make much sense for a staticlib which is built by cc rather than rustc, so adding -bundle
doesn't seem to have any downside for CXX-Qt's purposes.
Context
The CXX-Qt build system supports building two ways:
- Rust staticlib crate which gets linked with C++ code built by CMake using CMake's equivalent of
+whole-archive
:target_link_libraries(${APP_NAME}_lib INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,${CRATE}-static>")
- Rust bin crate
The Rust bin crate case is still working. The Rust staticlib case fails with the confusing error about rlibs in Rust 1.69. From the Zulip discussion, this seems to be a regression from #105601. This error should be ignored when the crate being built isn't an rlib.