There are a number of flags around debug info compression in gcc and binutils. Here, I'm interested in the interplay between the following four flags in a standard sort of C++ project that creates a number of object files with the compiler and then uses the compiler to drive a link step that combines the object files into various final binaries:
-Wa,--compress-debug-sections=zlib-gabi
-Wa,--nocompress-debug-sections
-Wl,--compress-debug-sections=zlib-gabi
-Wl,--compress-debug-sections=none
So, we can imagine four possibilities. We have compiled our object files with either no compression in the assembler or with -Wa,--compress-debug-sections=zlib-gabi
, and we have linked our object files into binaries with either no compression in the linker or with -Wl,--compress-debug-sections=zlib-gabi
enabled.
The combination -Wa,--nocompress-debug-sections
for compile and -Wl,--compress-debug-sections=none
is uninteresting. Presumably no compression at all takes place.
The next two combinations are somewhat more interesting:
With
-Wa,--compress-debug-sections=zlib-gabi
for the assembler and-Wl,--compress-debug-sections=none
for the linker, it seems like the linker would need to spend time to uncompress the debug information from each object file before merging it and emitting new uncompressed debug info sections for the final binaries.With
-Wa,--nocompress-debug-sections
for the assembler and-Wl,--compress-debug-sections=zlib-gabi
for the linker, it seems clear that the assembler won't spend time compressing the debug info for the object files, and the linker will spend time compressing the final merged debug info sections.
Are my assumptions and understanding of these two cases mostly correct? If not, what have I misunderstood?
That leaves the most interesting case:
- With
-Wa,--compress-debug-sections=zlib-gabi
to the assembler AND-Wl,--compress-debug-sections=zlib-gabi
to the linker, what happens here? If my understanding for the above cases is correct, I'd expect that the assembler would do the work to compress debug information in each object file, and then the linker would need to spend time decompressing it, then do merging, and finally recompress the merged debug info sections. Is that correct? Or is the linker somehow able to magically directly merge the compressed debug info sections in the object files directly into the final compressed debug info sections for the link step, avoiding the uncompress/recompress cycle?
Overall, I'm just looking to understand what I should default these flags to in the build system for the best build performance. I'll of course do some benchmarking, but I'm interested to understand the theory of operation here as well, as it will help me understand any build benchmark results around these flags.