[PATCH v2] libstdc++: Add module initialization functions to the library [PR124268]
Jonathan Wakely
jwakely@redhat.com
Thu Apr 16 15:31:57 GMT 2026
On Thu, 16 Apr 2026 at 16:20, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> This tries to ensure that the module init functions are present in
> libstdc++.so and libstdc++.a, so that users of the std and std.compat
> modules don't need to manually link to std.o and/or std.compat.o in
> addition to compiling the CMIs.
>
> This also adds a clean-local target to remove the generated interface
> units and manifest, and the gcm.cache directory for the CMIs.
>
> This was previously committed and then reverted because it broke
> bootstrap on a few targets. Most of the reasons the module interface
> units failed to compile have (we believe) now been addressed with G++
> changes, although there's still a problem on amdgcn (PR124554). Due to
> that problem, and any not yet known problems, this version of the patch
> tries to avoid breaking bootstrap again by allowing the modules to fail
> to compile. If compiling std.o or std.compat.o fails then an empty
> translation unit will be compiled and added to libstdc++.so instead.
>
> This means that we will only export the module initialization functions
> from the library if the module can be compiled for the target. This
> seems fine because we don't need to initialize anything for a module
> that cannot even be compiled! Fixing PR124554 and removing this kluge
> should be done for GCC 17 in stage 1.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/124268
> * config/abi/pre/gnu.ver: Export symbols.
> * src/Makefile.am: Add libmodulesconvenience.la to libstdc++
> link.
> * src/Makefile.in: Regenerate.
> * src/c++23/Makefile.am: Create libmodulesconvenience.la
> and populate it with std.o and std.compat.o interface units,
> with empty fallback objects if compiling the interface units
> fails. Add clean-local target.
> * src/c++23/Makefile.in: Regenerate.
> ---
>
> v2: Replace the module interface units with empty translation units if
> they fail to compile.
>
> Tested x86_64-linux, sparc-solaris, aarch64-linux.
>
> Bootstrapped on xtensa-esp32-elf before Jakub's r16-8703 and this patch
> allows bootstrap to complete even though std.cc fails:
>
> std.cc:4150:14: error: exporting 'typedef __gnuc_va_list va_list' that does not have external linkage
> 4150 | using std::va_list;
> | ^~~~~~~
> <built-in>: note: 'typedef struct __va_list_tag __va_list_tag' declared here with internal linkage
> Cannot compile std module
> Module initialization function will be missing
Also successfully bootstrapped on x86_64-unknown-freebsd16.0 which has
the upstream fix for the static inline fenv.h functions and on
x86_64-unknown-freebsd14.0 which does not have the upstream fix and so
would have failed to compile std.cc without Nathaniel's
r16-8488-g8b9a294a484ed5. It now compiles, and adds std.o to
libstdc++.so for both freebsd targets.
>
> libstdc++-v3/config/abi/pre/gnu.ver | 4 ++
> libstdc++-v3/src/Makefile.am | 6 ++-
> libstdc++-v3/src/Makefile.in | 6 ++-
> libstdc++-v3/src/c++23/Makefile.am | 45 ++++++++++++++++-
> libstdc++-v3/src/c++23/Makefile.in | 76 +++++++++++++++++++++++------
> 5 files changed, 117 insertions(+), 20 deletions(-)
>
> diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
> index 71b3c175bbdf..bd4da6418295 100644
> --- a/libstdc++-v3/config/abi/pre/gnu.ver
> +++ b/libstdc++-v3/config/abi/pre/gnu.ver
> @@ -2617,6 +2617,10 @@ GLIBCXX_3.4.35 {
> _ZSt15__get_once_callv;
> #endif
>
> + # Module inititialization symbols for std and std.compat modules.
> + _ZGIW3std;
> + _ZGIW3stdW6compat;
> +
> } GLIBCXX_3.4.34;
>
> # Symbols in the support library (libsupc++) have their own tag.
> diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
> index 55a8c88a0e12..35a497a15886 100644
> --- a/libstdc++-v3/src/Makefile.am
> +++ b/libstdc++-v3/src/Makefile.am
> @@ -145,7 +145,8 @@ libstdc___la_LIBADD = \
> $(top_builddir)/src/c++98/libc++98convenience.la \
> $(top_builddir)/src/c++11/libc++11convenience.la \
> $(top_builddir)/src/c++17/libc++17convenience.la \
> - $(top_builddir)/src/c++20/libc++20convenience.la
> + $(top_builddir)/src/c++20/libc++20convenience.la \
> + $(top_builddir)/src/c++23/libmodulesconvenience.la
>
> libstdc___la_DEPENDENCIES = \
> ${version_dep} \
> @@ -153,7 +154,8 @@ libstdc___la_DEPENDENCIES = \
> $(top_builddir)/src/c++98/libc++98convenience.la \
> $(top_builddir)/src/c++11/libc++11convenience.la \
> $(top_builddir)/src/c++17/libc++17convenience.la \
> - $(top_builddir)/src/c++20/libc++20convenience.la
> + $(top_builddir)/src/c++20/libc++20convenience.la \
> + $(top_builddir)/src/c++23/libmodulesconvenience.la
>
> if ENABLE_DARWIN_AT_RPATH
> libstdc___darwin_rpath = -Wc,-nodefaultrpaths
> diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
> index f0ad019a71fd..811d0a5ce4a8 100644
> --- a/libstdc++-v3/src/Makefile.in
> +++ b/libstdc++-v3/src/Makefile.in
> @@ -555,7 +555,8 @@ libstdc___la_LIBADD = \
> $(top_builddir)/src/c++98/libc++98convenience.la \
> $(top_builddir)/src/c++11/libc++11convenience.la \
> $(top_builddir)/src/c++17/libc++17convenience.la \
> - $(top_builddir)/src/c++20/libc++20convenience.la
> + $(top_builddir)/src/c++20/libc++20convenience.la \
> + $(top_builddir)/src/c++23/libmodulesconvenience.la
>
> libstdc___la_DEPENDENCIES = \
> ${version_dep} \
> @@ -563,7 +564,8 @@ libstdc___la_DEPENDENCIES = \
> $(top_builddir)/src/c++98/libc++98convenience.la \
> $(top_builddir)/src/c++11/libc++11convenience.la \
> $(top_builddir)/src/c++17/libc++17convenience.la \
> - $(top_builddir)/src/c++20/libc++20convenience.la
> + $(top_builddir)/src/c++20/libc++20convenience.la \
> + $(top_builddir)/src/c++23/libmodulesconvenience.la
>
> @ENABLE_DARWIN_AT_RPATH_TRUE@libstdc___darwin_rpath = \
> @ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \
> diff --git a/libstdc++-v3/src/c++23/Makefile.am b/libstdc++-v3/src/c++23/Makefile.am
> index b031ec69576c..5b2812abd228 100644
> --- a/libstdc++-v3/src/c++23/Makefile.am
> +++ b/libstdc++-v3/src/c++23/Makefile.am
> @@ -23,10 +23,13 @@
> include $(top_srcdir)/fragment.am
>
> # Convenience library for C++23 runtime.
> -noinst_LTLIBRARIES = libc++23convenience.la
> +# This libc++23convenience.la one isn't linked into libstdc++.la yet,
> +# so build an additional libmodulesconvenience.la which is linked in.
> +noinst_LTLIBRARIES = libc++23convenience.la libmodulesconvenience.la
>
> -# Module std support. Not compiled for now, only installed.
> +# Module std support.
> # Let's install the interface units in the bits subdirectory.
> +# We also compile them and include them in libmodulesconvenience.la
> toolexeclib_DATA = libstdc++.modules.json
> includebitsdir = $(gxx_include_dir)/bits
> includebits_DATA = std.cc std.compat.cc
> @@ -59,6 +62,9 @@ stamp-modules-bits: $(includebits_DATA)
>
> all-local: stamp-module-manifest stamp-modules-bits
>
> +clean-local:
> + rm -rf stamp* libstdc++.modules.json std.cc std.compat.cc gcm.cache
> +
> headers =
>
> if ENABLE_EXTERN_TEMPLATE
> @@ -80,12 +86,47 @@ else
> libc__23convenience_la_SOURCES =
> endif
>
> +libmodulesconvenience_la_SOURCES = std.cc std.compat.cc
> +
> # Use C++26 so that std::filebuf::native_handle() is available.
> print.lo: print.cc
> $(LTCXXCOMPILE) -std=gnu++26 -c $<
> print.o: print.cc
> $(CXXCOMPILE) -std=gnu++26 -c $<
>
> +MODULES_FLAGS = -isystem ${glibcxx_srcdir}/include/backward -fmodules \
> + -Wno-unknown-pragmas
> +
> +# These go into libmodulesconvenience.la and are linked into libstdc++
> +std.lo: std.cc
> + if ! $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +std.o: std.cc
> + if ! $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +std.compat.lo: std.compat.cc std.lo
> + if ! $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std.compat module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +std.compat.o: std.compat.cc std.o
> + if ! $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std.compat module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +
> # AM_CXXFLAGS needs to be in each subdirectory so that it can be
> # modified in a per-library or per-sub-library way. Need to manually
> # set this option because CONFIG_CXXFLAGS has to be after
> diff --git a/libstdc++-v3/src/c++23/Makefile.in b/libstdc++-v3/src/c++23/Makefile.in
> index fd9110ab8ad2..75da9c008ab6 100644
> --- a/libstdc++-v3/src/c++23/Makefile.in
> +++ b/libstdc++-v3/src/c++23/Makefile.in
> @@ -133,6 +133,10 @@ AM_V_lt = $(am__v_lt_@AM_V@)
> am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
> am__v_lt_0 = --silent
> am__v_lt_1 =
> +libmodulesconvenience_la_LIBADD =
> +am_libmodulesconvenience_la_OBJECTS = std.lo std.compat.lo
> +libmodulesconvenience_la_OBJECTS = \
> + $(am_libmodulesconvenience_la_OBJECTS)
> AM_V_P = $(am__v_P_@AM_V@)
> am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
> am__v_P_0 = false
> @@ -159,7 +163,8 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
> am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
> am__v_CXXLD_0 = @echo " CXXLD " $@;
> am__v_CXXLD_1 =
> -SOURCES = $(libc__23convenience_la_SOURCES)
> +SOURCES = $(libc__23convenience_la_SOURCES) \
> + $(libmodulesconvenience_la_SOURCES)
> am__can_run_installinfo = \
> case $$AM_UPDATE_INFO_DIR in \
> n|no|NO) false;; \
> @@ -457,10 +462,13 @@ WARN_CXXFLAGS = \
> AM_CPPFLAGS = $(GLIBCXX_INCLUDES) $(CPPFLAGS)
>
> # Convenience library for C++23 runtime.
> -noinst_LTLIBRARIES = libc++23convenience.la
> +# This libc++23convenience.la one isn't linked into libstdc++.la yet,
> +# so build an additional libmodulesconvenience.la which is linked in.
> +noinst_LTLIBRARIES = libc++23convenience.la libmodulesconvenience.la
>
> -# Module std support. Not compiled for now, only installed.
> +# Module std support.
> # Let's install the interface units in the bits subdirectory.
> +# We also compile them and include them in libmodulesconvenience.la
> toolexeclib_DATA = libstdc++.modules.json
> includebitsdir = $(gxx_include_dir)/bits
> includebits_DATA = std.cc std.compat.cc
> @@ -473,6 +481,10 @@ headers =
> sources = stacktrace.cc print.cc
> @GLIBCXX_HOSTED_FALSE@libc__23convenience_la_SOURCES =
> @GLIBCXX_HOSTED_TRUE@libc__23convenience_la_SOURCES = $(sources) $(inst_sources)
> +libmodulesconvenience_la_SOURCES = std.cc std.compat.cc
> +MODULES_FLAGS = -isystem ${glibcxx_srcdir}/include/backward -fmodules \
> + -Wno-unknown-pragmas
> +
>
> # AM_CXXFLAGS needs to be in each subdirectory so that it can be
> # modified in a per-library or per-sub-library way. Need to manually
> @@ -586,6 +598,9 @@ clean-noinstLTLIBRARIES:
> libc++23convenience.la: $(libc__23convenience_la_OBJECTS) $(libc__23convenience_la_DEPENDENCIES) $(EXTRA_libc__23convenience_la_DEPENDENCIES)
> $(AM_V_CXXLD)$(CXXLINK) $(libc__23convenience_la_OBJECTS) $(libc__23convenience_la_LIBADD) $(LIBS)
>
> +libmodulesconvenience.la: $(libmodulesconvenience_la_OBJECTS) $(libmodulesconvenience_la_DEPENDENCIES) $(EXTRA_libmodulesconvenience_la_DEPENDENCIES)
> + $(AM_V_CXXLD)$(CXXLINK) $(libmodulesconvenience_la_OBJECTS) $(libmodulesconvenience_la_LIBADD) $(LIBS)
> +
> mostlyclean-compile:
> -rm -f *.$(OBJEXT)
>
> @@ -739,8 +754,8 @@ maintainer-clean-generic:
> @echo "it deletes files that may require special tools to rebuild."
> clean: clean-am
>
> -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
> - mostlyclean-am
> +clean-am: clean-generic clean-libtool clean-local \
> + clean-noinstLTLIBRARIES mostlyclean-am
>
> distclean: distclean-am
> -rm -f Makefile
> @@ -809,15 +824,15 @@ uninstall-am: uninstall-includebitsDATA uninstall-toolexeclibDATA
> .MAKE: install-am install-strip
>
> .PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \
> - clean-generic clean-libtool clean-noinstLTLIBRARIES \
> - cscopelist-am ctags ctags-am distclean distclean-compile \
> - distclean-generic distclean-libtool distclean-tags dvi dvi-am \
> - html html-am info info-am install install-am install-data \
> - install-data-am install-dvi install-dvi-am install-exec \
> - install-exec-am install-html install-html-am \
> - install-includebitsDATA install-info install-info-am \
> - install-man install-pdf install-pdf-am install-ps \
> - install-ps-am install-strip install-toolexeclibDATA \
> + clean-generic clean-libtool clean-local \
> + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \
> + distclean-compile distclean-generic distclean-libtool \
> + distclean-tags dvi dvi-am html html-am info info-am install \
> + install-am install-data install-data-am install-dvi \
> + install-dvi-am install-exec install-exec-am install-html \
> + install-html-am install-includebitsDATA install-info \
> + install-info-am install-man install-pdf install-pdf-am \
> + install-ps install-ps-am install-strip install-toolexeclibDATA \
> installcheck installcheck-am installdirs maintainer-clean \
> maintainer-clean-generic mostlyclean mostlyclean-compile \
> mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
> @@ -855,6 +870,9 @@ stamp-modules-bits: $(includebits_DATA)
>
> all-local: stamp-module-manifest stamp-modules-bits
>
> +clean-local:
> + rm -rf stamp* libstdc++.modules.json std.cc std.compat.cc gcm.cache
> +
> vpath % $(top_srcdir)/src/c++23
>
> # Use C++26 so that std::filebuf::native_handle() is available.
> @@ -863,6 +881,36 @@ print.lo: print.cc
> print.o: print.cc
> $(CXXCOMPILE) -std=gnu++26 -c $<
>
> +# These go into libmodulesconvenience.la and are linked into libstdc++
> +std.lo: std.cc
> + if ! $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +std.o: std.cc
> + if ! $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +std.compat.lo: std.compat.cc std.lo
> + if ! $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std.compat module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(LTCXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +std.compat.o: std.compat.cc std.o
> + if ! $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; then \
> + echo "Cannot compile std.compat module" >&2; \
> + echo "Module initialization function will be missing" >&2; \
> + echo > $<.tmp && mv $<.tmp $< && \
> + $(CXXCOMPILE) $(MODULES_FLAGS) -c $< ; \
> + fi
> +
> # Tell versions [3.59,3.63) of GNU make to not export all variables.
> # Otherwise a system limit (for SysV at least) may be exceeded.
> .NOEXPORT:
> --
> 2.53.0
>
More information about the Libstdc++
mailing list