These flags are defined in GCC’s spec files, so the best way to determine the differences between them is to look there:
gcc -dumpspecs
The relevant part is the link_command
definition. This shows that -nostdlib
, -nodefaultlibs
and -nostartfiles
have the following impact:
%{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}}
— this adds libgcc
, libpthread
, libc
, libieee
as necessary, using a macro and the lib
and libgcc
spec strings;
%{!nostdlib:%{!nostartfiles:%S}}
— this adds the startfile
spec string, , which specifies the object files to add to handle startup (crti.o
etc.)
%{!nostdlib:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end} %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}
— this adds virtual table verification using libvtv
%{!nostdlib:%{!nodefaultlibs:%{mmpx:%{fcheck-pointer-bounds: %{static:--whole-archive -lmpx --no-whole-archive %:include(libmpx.spec)%(link_libmpx)} %{!static:%{static-libmpx:-Bstatic --whole-archive} %{!static-libmpx:--push-state --no-as-needed} -lmpx %{!static-libmpx:--pop-state} %{static-libmpx:--no-whole-archive -Bdynamic %:include(libmpx.spec)%(link_libmpx)}}}}%{mmpx:%{fcheck-pointer-bounds:%{!fno-chkp-use-wrappers: %{static:-lmpxwrappers} %{!static:%{static-libmpxwrappers:-Bstatic} -lmpxwrappers %{static-libmpxwrappers: -Bdynamic}}}}}}}
— this handles libmpx
%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address): %{static-libasan:%:include(libsanitizer.spec)%(link_libasan)} %{static:%ecannot specify -static with -fsanitize=address}} %{%:sanitize(thread): %{static-libtsan:%:include(libsanitizer.spec)%(link_libtsan)} %{static:%ecannot specify -static with -fsanitize=thread}} %{%:sanitize(undefined):%{static-libubsan:-Bstatic} -lubsan %{static-libubsan:-Bdynamic} %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}} %{%:sanitize(leak): %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}}}}
— this handles the various sanitisation options
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}
— this adds the stack protection options and repeats the C link sequence (whose libraries were already specified at the start)
%{!nostdlib:%{!nostartfiles:%E}}
— this adds the endfile
spec string, which specifies the object files to add to handle left-overs (crtfastmath.o
, crtend.o
etc.)
As you understood from the documentation, -nostdlib
is a superset of -nodefaultlibs
and -nostartfiles
. It also disables virtual table verification.
So -nostdlib
is sufficient to disable all the related features; -nodefaultlibs
and -nostartfiles
don’t add anything to it. (But it doesn’t hurt to mention them too.)