Re: libgcc/crtstuff.c compiled twice, and forced to -O2

Xi Ruoyao via Gcc-help <[email protected]> Sun, 21 Jun 2026 02:20:05 +0800
Newsgroups gmane.comp.gcc.help
Message-ID <[email protected]>
On Sat, 2026-06-20 at 17:42 +0200, Georg-Johann Lay via Gcc-help wrote:
> Am 20.06.26 um 15:47 schrieb R. Diez via Gcc-help:
> > Hi all:
> >=20
> > I am building a cross-compiler toolchain for an embedded ARM target, se=
e=20
> > here: https://github.com/rdiez/DebugDue/tree/master/Toolchain
> >=20
> > I recently had to debug an issue on start-up, and that was harder then=
=20
> > necessary, as libgcc/crtstuff.c is not built with debug information, se=
e=20
> > here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D125899
> >=20
> > During my investigation, I have also realised the following:
> >=20
> > 1) File libgcc/crtstuff.c is compiled twice, once with -DCRT_BEGIN and=
=20
> > once with -DCRT_END.
> >=20
> > Those options are apparently mutually exclusive. The file is split in=
=20
> > half, one with #ifdef CRT_BEGIN, and the other with #ifdef CRT_END.
> >=20
> > Shouldn't this file be split into 2 files then?
> >=20
> > Or should we just get rid of CRT_BEGIN and CRT_END and compile the file=
=20
> > only once?
> >=20
> > There is one variant though which is compiled only with -DCRT_BEGIN,
> > according to this comment in file "libgcc/Makefile.in":
> >=20
> > # This is a version of crtbegin for -static links.
> >=20
> > I wonder why. Does a static build not need to call global destructors?
> >=20
> > My single-threaded, bare metal toolchain has no dynamic library / share=
d=20
> > object support, but crtstuff.c is still getting compiled twice with -=
=20
> > DCRT_BEGIN and -DCRT_END, and global destructors are called on terminat=
ion.
> >=20
> > Proper termination is not very common in embedded software, but I am
>=20
> It will become common once you start running testsuites.
>=20
>=20
> > triggering it manually in order to debug memory leaks.
> >=20
> >=20
> > 2) crtstuff.c is forcedly compiled with -O2, according to this in file=
=20
> > "libgcc/Makefile.in":
> >=20
> > # Options to use when compiling crtbegin/end.
> > CRTSTUFF_CFLAGS =3D -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g=
0 \
> > =C2=A0=C2=A0 $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno=
-exceptions \
> > =C2=A0=C2=A0 -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tr=
ee-vectorize \
> > =C2=A0=C2=A0 -fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH=
_REGISTRY) \
> > =C2=A0=C2=A0 $(INHIBIT_LIBC_CFLAGS) $(USE_TM_CLONE_REGISTRY)
> >=20
> > I would say it does not make sense to always force -O2, or does it?
>=20
> Can't you override it in your MULTILIB_CFLAGS?

You can also override it with CFLAGS_FOR_TARGET, as documented by
https://gcc.gnu.org/install/build.html.

/* snip */

> > Does it make sense anyway to specify -O2 f=C3=BCr a single file? Will i=
t not=20
> > be overridden by LTO anyway?

It's not only for a single file.  Despite it's named "CRTSTUFF_CFLAGS"
it's actually pulled into ALL_CRT_CFLAGS:

ALL_CRT_CFLAGS =3D $(CFLAGS) $(CRTSTUFF_CFLAGS) $(INCLUDES)

which is used for several files in libgcc.

--=20
Xi Ruoyao <[email protected]>