-save-temps
The advantage of this option over -E is that it is easy to add it to any build script, without interfering much in the build itself:
gcc -save-temps -c -o main.o main.c
main.c
#define INC 1 int myfunc(int i) { return i + INC; }
and now, besides the normal output main.o, the current working directory also contains the following files:
main.i is the desired prepossessed file containing:
# 1 "main.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "main.c" int myfunc(int i) { return i + 1; }
main.s is a bonus :-) and contains the generated assembly:
.file "main.c" .text .globl myfunc .type myfunc, @function myfunc: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -4(%rbp) movl -4(%rbp), %eax addl $1, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size myfunc, .-myfunc .ident "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0" .section .note.GNU-stack,"",@progbits
Docs: https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html#index-save-temps
-save-temps=obj
If you want to do it for a large number of files, consider using instead:
-save-temps=obj
which saves the intermediate files to the same directory as the -o object output instead of the current working directory, thus avoiding potential basename conflicts.
For example:
gcc -save-temps -c -o out/subdir/main.o subdir/main.c
leads to the creation of files:
out/subdir/main.i out/subdir/main.o out/subdir/main.s
Clearly an Apple plot to take over the world.
-save-temps -v
Another cool thing about this option is if you add -v:
gcc -save-temps -c -o main.o -v main.c
it actually shows the explicit files being used instead of ugly temporaries under /tmp, so it is easy to know exactly what is going on, which includes the preprocessing / compilation / assembly steps:
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu main.c -mtune=generic -march=x86-64 -fpch-preprocess -fstack-protector-strong -Wformat -Wformat-security -o main.i /usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed main.i -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase-strip main.o -version -fstack-protector-strong -Wformat -Wformat-security -o main.s as -v --64 -o main.o main.s
Tested in Ubuntu 19.04 (Disco Dingo) amd64, GCC 8.3.0.
CMake predefined targets
CMake automatically provides a targets for the preprocessed file:
make help
shows us that we can do:
make main.i
and that target runs:
Preprocessing C source to CMakeFiles/main.dir/main.c.i /usr/bin/cc -E /home/ciro/bak/hello/main.c > CMakeFiles/main.dir/main.c.i
so the file can be seen at CMakeFiles/main.dir/main.c.i
Tested on cmake 3.16.1.
gcc -Eis more useful than having to rewrite the line to make it work withcpp.gcc -save-tempsI suggest to take a look.