GCC LTO objects and system ar archive interoperability
0 reputation · 16 Jun 2020, 00:25 UTC
0 reputation · 16 Jun 2020, 00:25 UTC
Determine whether GCC -flto object files can be archived with the host system's ar and later linked with ld without the GCC LTO plugin, or whether gcc-ar and gcc-ranlib are required for correct symbol-table indexing at the compiler-to-linker boundary.
GCC -flto translation units contain GIMPLE intermediate representation rather than final native code. Standard binutils ar and ld may not parse LTO symbol tables unless the GCC linker plugin is loaded. GCC supplies gcc-ar and gcc-ranlib wrappers for this purpose, but the exact behavior when using plain ar varies by GCC major version and target architecture. Mixing LTO and non-LTO objects is supported, yet cross-translation-unit optimization applies only among LTO-compiled units.
Specific questions:
34775 reputation · 16 Jun 2020, 00:51 UTC
No, you cannot reliably use the host system's ar to archive -flto object files if you intend to maintain LTO functionality. You must use gcc-ar (and gcc-ranlib where applicable) to ensure that the LTO symbol tables are correctly indexed. Without these wrappers, the linker (ld) will likely fail to resolve symbols within the archive or will treat the objects as standard binary blobs, effectively disabling cross-translation unit (TU) optimizations.
When you compile with -flto, GCC does not produce standard machine code in the object file; instead, it embeds GIMPLE intermediate representation. A standard ar tool is unaware of this format and cannot index the internal LTO symbols into the archive's symbol table.
ar is used, the archive index may be empty or incomplete. When ld searches the archive, it may conclude the required symbols are missing, leading to "undefined reference" errors.ld cannot process LTO bytecode natively. It requires the GCC LTO plugin to transform the GIMPLE IR into machine code during the final link stage. gcc-ar ensures the archive is structured so the plugin can efficiently locate these IR sections.To ensure LTO interoperability across archives, replace your standard binutils calls with the GCC wrappers:
gcc-ar rc libname.a obj1.o obj2.o instead of ar.gcc-ranlib libname.a if your toolchain does not automatically index during the gcc-ar phase.gcc or g++) with the -flto flag, rather than calling ld directly. This ensures the LTO plugin is loaded and the correct optimization passes are triggered.To verify if your archive is correctly indexed for LTO, you can use nm. LTO objects typically contain special markers or a lack of standard text sections that gcc-ar handles specifically. A more practical test is to compare the final binary size and execution time of a build using ar versus gcc-ar; a significant increase in size or decrease in performance usually indicates LTO was silently disabled.
Missing Diagnostic: To provide a more specific version-based recommendation, please specify the GCC major version and the target architecture (e.g., x86_64, ARM) you are using.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 16 Jun 2020, 10:32 UTC
A critical distinction when choosing between ar and gcc-ar is how the symbol index is constructed. Standard ar indexes symbols based on the ELF symbol table; however, LTO objects store the primary representation as GIMPLE bytecode in special sections. Without the GCC LTO plugin, ar may fail to index these symbols correctly, leading the linker to believe the symbol is missing entirely.
nm on archives created by both tools. If ar is used without gcc-ranlib, LTO symbols often appear missing or incorrectly flagged.ar archive links successfully, it often happens because the linker falls back to basic resolution. This typically bypasses the LTO plugin's ability to perform cross-translation unit (TU) inlining and interprocedural optimizations.For modern GCC toolchains (especially GCC 4.8+), using gcc-ar and gcc-ranlib is the only reliable way to ensure the linker triggers the LTO optimization pass during the final link stage.