Skip to content

Commit 9222758

Browse files
authored
cpp_build: disable LTO to preserve metadata in .data section (#116)
The cpp crate communicates type metadata (sizes, alignments, trait flags) from the build script to the proc-macro by embedding a struct with a magic byte pattern in the .data section of the compiled static library. The proc-macro then scans the .a file for this pattern using aho-corasick. When LTO is enabled via environment CXXFLAGS (e.g. -flto=auto, as is the default on Arch Linux's makepkg), the C++ compiler emits GIMPLE intermediate representation instead of native machine code. This leaves the .data and .text sections empty — all content lives in .gnu.lto_* sections as serialized IR. The magic bytes are no longer visible to the byte-level scan, causing the proc-macro to panic with: "Struct metadata not present in target library file." Fix this by passing -fno-lto when compiling the generated C++ library. This ensures the metadata struct is always present as raw bytes in .data, regardless of the environment's LTO settings. Fixes builds on distributions that enable LTO by default (Arch Linux, Fedora, Gentoo with LTO profiles).
1 parent cc63bb0 commit 9222758

1 file changed

Lines changed: 9 additions & 0 deletions

File tree

cpp_build/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,15 @@ In order to provide a better error message, the build script will exit successfu
654654
if !self.std_flag_set {
655655
self.cc.flag_if_supported("-std=c++11");
656656
}
657+
// Disable LTO for the generated C++ library. The cpp crate embeds
658+
// metadata as raw bytes in the .data section of the compiled object,
659+
// which the cpp_macros proc-macro later locates via byte pattern
660+
// matching. When LTO is enabled (e.g. -flto=auto from environment
661+
// CXXFLAGS), the compiler emits GIMPLE IR instead of native code,
662+
// leaving the .data section empty and making the metadata invisible
663+
// to the proc-macro.
664+
self.cc.flag_if_supported("-fno-lto");
665+
657666
// Build the C++ library
658667
if let Err(e) = self.cc.file(filename).try_compile(LIB_NAME) {
659668
let _ = writeln!(std::io::stderr(), "\n\nerror occurred: {}\n\n", e);

0 commit comments

Comments
 (0)