GCC verbose mode output explanation
The first part is the version and configuration data for the compiler driver (that's the gcc
binary, which is not actually the compiler itself):
Reading specs from /usr/lib/gcc-lib/i686/3.3.1/specs
Configured with: ../configure --prefix=/usr
Thread model: posix
gcc version 3.3.1
Then it prints the command it uses to call the real compiler, cc1
:
/usr/lib/gcc-lib/i686/3.3.1/cc1 -quiet -v -D__GNUC__=3
-D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=1
hello.c -quiet -dumpbase hello.c -auxbase hello -Wall
-version -o /tmp/cceCee26.s
And cc1
prints it's version and config info.
GNU C version 3.3.1 (i686-pc-linux-gnu)
compiled by GNU C version 3.3.1 (i686-pc-linux-gnu)
GGC heuristics: --param ggc-min-expand=51
--param ggc-min-heapsize=40036
Then cc1
tells you what directories it will search for include files.
ignoring nonexistent directory "/usr/i686/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include
/usr/lib/gcc-lib/i686/3.3.1/include
/usr/include
End of search list.
The compiler is now complete, so gcc
tells you the assembler command it will use.
as -V -Qy -o /tmp/ccQynbTm.o /tmp/cceCee26.s
And the assembler, as
, gives its version info.
GNU assembler version 2.12.90.0.1 (i386-linux)
using BFD version 2.12.90.0.1 20020307 Debian/GNU
Linux
The assembler is now done so gcc
gives the linker command. It's using collect2
as an intermediary to the real linker ld
, but that's not important here.
/usr/lib/gcc-lib/i686/3.3.1/collect2
--eh-frame-hdr -m elf_i386 -dynamic-linker
/lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/gcc-lib/i686/3.3.1/crtbegin.o
-L/usr/lib/gcc-lib/i686/3.3.1
-L/usr/lib/gcc-lib/i686/3.3.1/../../.. /tmp/ccQynbTm.o
-lgcc -lgcc_eh -lc -lgcc -lgcc_eh
/usr/lib/gcc-lib/i686/3.3.1/crtend.o
/usr/lib/crtn.o
The linker gives no verbose output (try -Wl,-v
), so that's it.
The "crt" files mean "C RunTime". They are small sections of code inserted at the start of your program, and at the end. They take care of initialising your global variables, heap, and stack. They call atexit
functions after you return from main
. And some more besides.
Hope that helps.
More verbose mode for included files in GCC
Pass the -H
(preprocessor) option to g++
, generally by adding that in your Makefile
e.g. adding
CXXFLAGS += -H
at an appropriate place of your Makefile
You might simply try make CXX='g++ -H -Wall'
on the terminal.
If you type g++
in your terminal, add -H
just after it.
Why does gcc generate verbose assembly code?
First, as Mysticial commented, you should turn on some optimizations. Try passing -O2
(or -O3
, or just -O1
) to gcc
. If you want to understand more the generated assembly code, also pass -fverbose-asm
. If you want to understand why the code is generated (or not generated), learn GCC internals (perhaps pass also -fdump-tree-all
and -fdump-rtl-all
which produces a big lot of internal dump files).
Some slides on MELT (MELT is a domain specific language to extend GCC) might help and give other references.
You might be surprised by the amount of optimizations GCC can give you, when asked to. By default GCC does not optimize. There are some optimizations which you should explicitly ask for (not even done at -O3
).
Recent versions of GCC probably optimize more than older ones. Current GCC version in 2021 is GCC 11.
PS. I don't work anymore on MELT (abandoned it in 2017). in 2021, see also Bismon, RefPerSys, Frama-C.
what does ld -m --verbose actually do?
The ld -m option is used while linking .o files to create an executable file for a hardware platform provided as an argument with -m option.
E.g. if you specify ld -m elf_x86_64 ..., an executable file is created (assuming no error occurred) that can run on a x86_64 system. This is generally used during cross compiling. i.e. in the situation when you are trying to create an executable for a platform different from the one it is being built.
Flags to enable thorough and verbose g++ warnings
D'oh, all of my original searches turned up 99% of posts on how to suppress warnings (scarily enough), but I just ran across this comment, which has this lovely set of flags (some less relevant):
Cross checked with:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-g -O -Wall -Weffc++ -pedantic \
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wconversion \
-Wdisabled-optimization \
-Werror -Wfloat-equal -Wformat=2 \
-Wformat-nonliteral -Wformat-security \
-Wformat-y2k \
-Wimplicit -Wimport -Winit-self -Winline \
-Winvalid-pch \
-Wlong-long \
-Wmissing-field-initializers -Wmissing-format-attribute \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked -Wpadded -Wpointer-arith \
-Wredundant-decls \
-Wshadow -Wstack-protector \
-Wstrict-aliasing=2 -Wswitch-default \
-Wswitch-enum \
-Wunreachable-code -Wunused \
-Wunused-parameter \
-Wvariadic-macros \
-Wwrite-strings
So, I think that's a good starting point. Didn't realize this was a dupe, but at least it was deeply buried. :-)
Bazel build verbose compiler commands logging
This is probably what you are looking for:
bazel build --subcommands //my:target
The --subcommands
option causes Bazel's execution phase to print the full command line for each command prior to executing it.
Related Topics
Jmeter - Loopback Address Error When Launching Jmeter-Server on Linux
How to Recursively List All Files and Directories
Bash: /Bin/Tar: Argument List Too Long When Compressing Many Files with Tar
How to Conveniently Sync a File Between Two Git Repositories
How to Use Curl in a Shell Script
Openssh Client Hangs on Logout When Forwarding X Connections
Lowering Linux Kernel Timer Frequency
Why Would It Be Impossible to Fully Statically Link an Application
Linux Makefile Structure and Documentation
What Is the Fastest Way to Find All the File with the Same Inode
How to Dump Part of Binary File
How to Remove Jenkins Completely from Linux
Maximum Number of Inodes in a Directory
Maximum Resident Set Size Does Not Make Sense
How to Make Find and Printf Works in Bash Script
How to Run a Mips Binary on X86 Platform
Check If Vt-X Is Activated Without Having to Reboot in Linux