Raj Raj - 2 months ago 21
C Question

GCC save temporary output with extra information

I want to analyze the assembly output of the C program that I am compiling.
To enable GCC save the temporary file I added

-save-temps
option while compiling.

In another link I found following GCC options to produce extra output in the assembly code. How to use this option in conjunction with
-save-temps
to produce more readable assembly output? I also want to be sure that assembly file that I am viewing corresponds to the binary produced by the GCC.


-a[sub-option...] turn on listings
Sub-options [default hls]:
c omit false conditionals
d omit debugging directives
g include general info
h include high-level source
l include assembly
m include macro expansions
n omit forms processing
s include symbols
=FILE list to FILE (must be last sub-option)


Answer

Related: How to remove "noise" from GCC/clang assembly output?: lots of ways to make compiler asm output easier to read.


-Wa,xyz=FILE makes an extra output file alongside the normal output. It's orthogonal to -save-temps. If you want it to go to a file, you do need an extra output filename on the command line.

e.g. in a Makefile pattern rule:

%.o : %.c
        $(CC) -c  $(CFLAGS) $(CPPFLAGS) -Wa,-adhln=$*.lst $< -o $@

Put that in a file called Makefile (with the indent being a real TAB, not spaces), then you can:

$ CFLAGS='-O3 -g -fverbose-asm' make rnd10.o
cc -c  -O3 -g -fverbose-asm  -Wa,-adhln=rnd10.lst rnd10.c -o rnd10.o

$ ll rnd10.*
-rw-rw-r-- 1 peter peter 912 Mar  3  2016 rnd10.c
-rw-rw-r-- 1 peter peter 25K Sep  6 08:23 rnd10.lst
-rw-rw-r-- 1 peter peter 12K Sep  6 08:23 rnd10.o

So both the .o and the listing were created by the same command. If you used -save-temps, there's also be the preprocessed source, and the actual .s that was fed to the assembler, but there's probably not much point in saving those and a listing at the same time. (I chose .lst because it's not in a format that will assemble)


You may be able to get away with just adding -Wa,-adhln=$*.lst to your CFLAGS, instead of overriding the pattern rule. This will still only work for build systems that use Make, not alternatives that don't ultimately generate a Makefile (e.g. scons), because the $* expansion to the stem of the pattern rule is specific to Make. It also only works for Make pattern rules, not explicit foo.o : foo.c foo.h style rules.

e.g.

$ rm Makefile
$ CFLAGS='-O3 -g -fverbose-asm -Wa,-adhln=$*.lst' make rnd10.o
cc -O3 -g -fverbose-asm -Wa,-adhln=rnd10.lst   -c -o rnd10.o rnd10.c

Fun fact: Make doesn't even work with spaces in filenames, but you can protect from shell expansion of anything else (like foo$(echo)_weirdname.c with single quotes in the make rule and in CFLAGS).

Comments