[gcc r16-8714] libstdc++: Add module initialization functions to the library [PR124268]

Jonathan Wakely redi@gcc.gnu.org
Fri Apr 17 09:58:21 GMT 2026


https://gcc.gnu.org/g:9d02b118ee10506f90c7cf0e439108f48d370fc1

commit r16-8714-g9d02b118ee10506f90c7cf0e439108f48d370fc1
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Mar 11 21:05:13 2026 +0000

    libstdc++: Add module initialization functions to the library [PR124268]
    
    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.

Diff:
---
 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:


More information about the Libstdc++-cvs mailing list