public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* [RFC] add regenerate Makefile target
@ 2024-03-13  8:02 Christophe Lyon
  2024-03-14 18:10 ` Simon Marchi
  0 siblings, 1 reply; 21+ messages in thread
From: Christophe Lyon @ 2024-03-13  8:02 UTC (permalink / raw)
  To: binutils, gdb, gcc; +Cc: Christophe Lyon

Hi!

After recent discussions on IRC and on the lists about maintainer-mode
and various problems with auto-generated source files, I've written
this small prototype.

Based on those discussions, I assumed that people generally want to
update autotools files using a script similar to autoregen.py, which
takes care of running aclocal, autoheader, automake and autoconf as
appropriate.

What is currently missing is a "simple" way of regenerating other
files, which happens normally with --enable-maintainer-mode (which is
reportedly broken).  This patch as a "regenerate" Makefile target
which can be called to update those files, provided
--enable-maintainer-mode is used.

I tried this approach with the following workflow for binutils/gdb:
- run autoregen.py in srcdir
- cd builddir
- configure --enable-maintainer-mode 
- make all-bfd all-libiberty regenerate -j1
- for gdb: make all -C gdb/data-directory -j1
- make all -jXXX

Making 'all' in bfd and libiberty is needed by some XXX-gen host
programs in opcodes.

The advantage (for instance for CI) is that we can regenerate files at
-j1, thus avoiding the existing race conditions, and build the rest
with -j XXX.

Among drawbacks:
- most sub-components use Makefile.am, but gdb does not: this may make
  maintenance more complex (different rules for different projects)
- maintaining such ad-hoc "regenerate" rules would require special
  attention from maintainers/reviewers
- dependency on -all-bfd and all-libiberty is probably not fully
   intuitive, but should not be a problem if the "regenerate" rules
   are used after a full build for instance

Of course Makefile.def/Makefile.tpl would need further cleanup as I
didn't try to take gcc into account is this patch.

Thoughts?

Thanks,

Christophe


---
 Makefile.def         |   37 +-
 Makefile.in          | 1902 ++++++++++++++++++++++++++++++++++++++++++
 Makefile.tpl         |    7 +
 bfd/Makefile.am      |    1 +
 bfd/Makefile.in      |    1 +
 binutils/Makefile.am |    1 +
 binutils/Makefile.in |    1 +
 gas/Makefile.am      |    1 +
 gas/Makefile.in      |    1 +
 gdb/Makefile.in      |    1 +
 gold/Makefile.am     |    2 +-
 gold/Makefile.in     |    2 +-
 gprof/Makefile.am    |    1 +
 gprof/Makefile.in    |    1 +
 ld/Makefile.am       |    1 +
 ld/Makefile.in       |    1 +
 opcodes/Makefile.am  |    2 +
 opcodes/Makefile.in  |    2 +
 18 files changed, 1952 insertions(+), 13 deletions(-)

diff --git a/Makefile.def b/Makefile.def
index 3e00a729a0c..42e71a9ffa2 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -39,7 +39,8 @@ host_modules= { module= binutils; bootstrap=true; };
 host_modules= { module= bison; no_check_cross= true; };
 host_modules= { module= cgen; };
 host_modules= { module= dejagnu; };
-host_modules= { module= etc; };
+host_modules= { module= etc;
+                missing= regenerate; };
 host_modules= { module= fastjar; no_check_cross= true; };
 host_modules= { module= fixincludes; bootstrap=true;
 		missing= TAGS;
@@ -73,7 +74,8 @@ host_modules= { module= isl; lib_path=.libs; bootstrap=true;
 		no_install= true; };
 host_modules= { module= gold; bootstrap=true; };
 host_modules= { module= gprof; };
-host_modules= { module= gprofng; };
+host_modules= { module= gprofng;
+                missing= regenerate; };
 host_modules= { module= gettext; bootstrap=true; no_install=true;
                 module_srcdir= "gettext/gettext-runtime";
 		// We always build gettext with pic, because some packages (e.g. gdbserver)
@@ -95,7 +97,8 @@ host_modules= { module= tcl;
                 missing=mostlyclean; };
 host_modules= { module= itcl; };
 host_modules= { module= ld; bootstrap=true; };
-host_modules= { module= libbacktrace; bootstrap=true; };
+host_modules= { module= libbacktrace; bootstrap=true;
+                missing= regenerate; };
 host_modules= { module= libcpp; bootstrap=true; };
 // As with libiconv, don't install any of libcody
 host_modules= { module= libcody; bootstrap=true;
@@ -110,9 +113,11 @@ host_modules= { module= libcody; bootstrap=true;
 		missing= install-dvi;
 		missing=TAGS; };
 host_modules= { module= libdecnumber; bootstrap=true;
-		missing=TAGS; };
+		missing=TAGS;
+                missing= regenerate; };
 host_modules= { module= libgui; };
 host_modules= { module= libiberty; bootstrap=true;
+                missing= regenerate;
 	        extra_configure_flags='@extra_host_libiberty_configure_flags@';};
 // Linker plugins may need their own build of libiberty; see
 // gcc/doc/install.texi.  We take care that this build of libiberty doesn't get
@@ -134,16 +139,22 @@ host_modules= { module= libiconv;
 		missing= install-html;
 		missing= install-info; };
 host_modules= { module= m4; };
-host_modules= { module= readline; };
+host_modules= { module= readline;
+                missing= regenerate; };
 host_modules= { module= sid; };
-host_modules= { module= sim; };
+host_modules= { module= sim;
+                missing= regenerate; };
 host_modules= { module= texinfo; no_install= true; };
 host_modules= { module= zlib; no_install=true; no_check=true;
 		bootstrap=true;
+                missing= regenerate;
 	        extra_configure_flags='@extra_host_zlib_configure_flags@ @host_libs_picflag@';};
-host_modules= { module= gnulib; };
-host_modules= { module= gdbsupport; };
-host_modules= { module= gdbserver; };
+host_modules= { module= gnulib;
+                missing= regenerate; };
+host_modules= { module= gdbsupport;
+                missing= regenerate; };
+host_modules= { module= gdbserver;
+                missing= regenerate; };
 host_modules= { module= gdb; };
 host_modules= { module= expect; };
 host_modules= { module= guile; };
@@ -162,8 +173,10 @@ host_modules= { module= lto-plugin; bootstrap=true;
 		extra_make_flags='@extra_linker_plugin_flags@'; };
 host_modules= { module= libcc1; extra_configure_flags=--enable-shared; };
 host_modules= { module= gotools; };
-host_modules= { module= libctf; bootstrap=true; };
-host_modules= { module= libsframe; bootstrap=true; };
+host_modules= { module= libctf; bootstrap=true;
+                missing= regenerate; };
+host_modules= { module= libsframe; bootstrap=true;
+                missing= regenerate; };
 host_modules= { module= libgrust; };
 
 target_modules = { module= libstdc++-v3;
@@ -242,6 +255,8 @@ recursive_targets = { make_target= mostlyclean; };
 recursive_targets = { make_target= clean; };
 recursive_targets = { make_target= distclean; };
 recursive_targets = { make_target= maintainer-clean; };
+recursive_targets = { make_target= regenerate;
+		      depend=configure; };
 
 // Flags which need to be passed down.
 
diff --git a/Makefile.in b/Makefile.in
index a1f64a2ab5a..09631d62b72 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -2672,6 +2672,99 @@ maintainer-clean-target: maybe-maintainer-clean-target-libitm
 maintainer-clean-target: maybe-maintainer-clean-target-libatomic
 maintainer-clean-target: maybe-maintainer-clean-target-libgrust
 
+.PHONY: do-regenerate
+do-regenerate:
+	@: $(MAKE); $(unstage)
+	@r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(MAKE) $(RECURSE_FLAGS_TO_PASS) regenerate-host \
+	  regenerate-target
+
+
+.PHONY: regenerate-host
+
+regenerate-host: maybe-regenerate-bfd
+regenerate-host: maybe-regenerate-opcodes
+regenerate-host: maybe-regenerate-binutils
+regenerate-host: maybe-regenerate-bison
+regenerate-host: maybe-regenerate-cgen
+regenerate-host: maybe-regenerate-dejagnu
+regenerate-host: maybe-regenerate-etc
+regenerate-host: maybe-regenerate-fastjar
+regenerate-host: maybe-regenerate-fixincludes
+regenerate-host: maybe-regenerate-flex
+regenerate-host: maybe-regenerate-gas
+regenerate-host: maybe-regenerate-gcc
+regenerate-host: maybe-regenerate-gmp
+regenerate-host: maybe-regenerate-mpfr
+regenerate-host: maybe-regenerate-mpc
+regenerate-host: maybe-regenerate-isl
+regenerate-host: maybe-regenerate-gold
+regenerate-host: maybe-regenerate-gprof
+regenerate-host: maybe-regenerate-gprofng
+regenerate-host: maybe-regenerate-gettext
+regenerate-host: maybe-regenerate-tcl
+regenerate-host: maybe-regenerate-itcl
+regenerate-host: maybe-regenerate-ld
+regenerate-host: maybe-regenerate-libbacktrace
+regenerate-host: maybe-regenerate-libcpp
+regenerate-host: maybe-regenerate-libcody
+regenerate-host: maybe-regenerate-libdecnumber
+regenerate-host: maybe-regenerate-libgui
+regenerate-host: maybe-regenerate-libiberty
+regenerate-host: maybe-regenerate-libiberty-linker-plugin
+regenerate-host: maybe-regenerate-libiconv
+regenerate-host: maybe-regenerate-m4
+regenerate-host: maybe-regenerate-readline
+regenerate-host: maybe-regenerate-sid
+regenerate-host: maybe-regenerate-sim
+regenerate-host: maybe-regenerate-texinfo
+regenerate-host: maybe-regenerate-zlib
+regenerate-host: maybe-regenerate-gnulib
+regenerate-host: maybe-regenerate-gdbsupport
+regenerate-host: maybe-regenerate-gdbserver
+regenerate-host: maybe-regenerate-gdb
+regenerate-host: maybe-regenerate-expect
+regenerate-host: maybe-regenerate-guile
+regenerate-host: maybe-regenerate-tk
+regenerate-host: maybe-regenerate-libtermcap
+regenerate-host: maybe-regenerate-utils
+regenerate-host: maybe-regenerate-c++tools
+regenerate-host: maybe-regenerate-gnattools
+regenerate-host: maybe-regenerate-lto-plugin
+regenerate-host: maybe-regenerate-libcc1
+regenerate-host: maybe-regenerate-gotools
+regenerate-host: maybe-regenerate-libctf
+regenerate-host: maybe-regenerate-libsframe
+regenerate-host: maybe-regenerate-libgrust
+
+.PHONY: regenerate-target
+
+regenerate-target: maybe-regenerate-target-libstdc++-v3
+regenerate-target: maybe-regenerate-target-libsanitizer
+regenerate-target: maybe-regenerate-target-libvtv
+regenerate-target: maybe-regenerate-target-libssp
+regenerate-target: maybe-regenerate-target-newlib
+regenerate-target: maybe-regenerate-target-libgcc
+regenerate-target: maybe-regenerate-target-libbacktrace
+regenerate-target: maybe-regenerate-target-libquadmath
+regenerate-target: maybe-regenerate-target-libgfortran
+regenerate-target: maybe-regenerate-target-libobjc
+regenerate-target: maybe-regenerate-target-libgo
+regenerate-target: maybe-regenerate-target-libphobos
+regenerate-target: maybe-regenerate-target-libtermcap
+regenerate-target: maybe-regenerate-target-winsup
+regenerate-target: maybe-regenerate-target-libgloss
+regenerate-target: maybe-regenerate-target-libffi
+regenerate-target: maybe-regenerate-target-zlib
+regenerate-target: maybe-regenerate-target-rda
+regenerate-target: maybe-regenerate-target-libada
+regenerate-target: maybe-regenerate-target-libgm2
+regenerate-target: maybe-regenerate-target-libgomp
+regenerate-target: maybe-regenerate-target-libitm
+regenerate-target: maybe-regenerate-target-libatomic
+regenerate-target: maybe-regenerate-target-libgrust
+
 
 # Here are the targets which correspond to the do-X targets.
 
@@ -2871,6 +2964,13 @@ clang-format: $(srcdir)/.clang-format
 
 .PHONY: clang-format
 
+.PHONY: regenerate
+regenerate:
+	@: $(MAKE); $(unstage)
+	@r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(MAKE) $(RECURSE_FLAGS_TO_PASS) regenerate-host regenerate-target
+
 # Installation targets.
 
 .PHONY: install uninstall
@@ -4719,6 +4819,31 @@ maintainer-clean-bfd:
 
 @endif bfd
 
+.PHONY: maybe-regenerate-bfd regenerate-bfd
+maybe-regenerate-bfd:
+@if bfd
+maybe-regenerate-bfd: regenerate-bfd
+
+regenerate-bfd: \
+    configure-bfd 
+	@[ -f ./bfd/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in bfd"; \
+	(cd $(HOST_SUBDIR)/bfd && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif bfd
+
 
 
 .PHONY: configure-opcodes maybe-configure-opcodes
@@ -5859,6 +5984,31 @@ maintainer-clean-opcodes:
 
 @endif opcodes
 
+.PHONY: maybe-regenerate-opcodes regenerate-opcodes
+maybe-regenerate-opcodes:
+@if opcodes
+maybe-regenerate-opcodes: regenerate-opcodes
+
+regenerate-opcodes: \
+    configure-opcodes 
+	@[ -f ./opcodes/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in opcodes"; \
+	(cd $(HOST_SUBDIR)/opcodes && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif opcodes
+
 
 
 .PHONY: configure-binutils maybe-configure-binutils
@@ -6999,6 +7149,31 @@ maintainer-clean-binutils:
 
 @endif binutils
 
+.PHONY: maybe-regenerate-binutils regenerate-binutils
+maybe-regenerate-binutils:
+@if binutils
+maybe-regenerate-binutils: regenerate-binutils
+
+regenerate-binutils: \
+    configure-binutils 
+	@[ -f ./binutils/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in binutils"; \
+	(cd $(HOST_SUBDIR)/binutils && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif binutils
+
 
 
 .PHONY: configure-bison maybe-configure-bison
@@ -7470,6 +7645,32 @@ maintainer-clean-bison:
 
 @endif bison
 
+.PHONY: maybe-regenerate-bison regenerate-bison
+maybe-regenerate-bison:
+@if bison
+maybe-regenerate-bison: regenerate-bison
+
+regenerate-bison: \
+    configure-bison 
+	@: $(MAKE); $(unstage)
+	@[ -f ./bison/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in bison"; \
+	(cd $(HOST_SUBDIR)/bison && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif bison
+
 
 
 .PHONY: configure-cgen maybe-configure-cgen
@@ -7938,6 +8139,32 @@ maintainer-clean-cgen:
 
 @endif cgen
 
+.PHONY: maybe-regenerate-cgen regenerate-cgen
+maybe-regenerate-cgen:
+@if cgen
+maybe-regenerate-cgen: regenerate-cgen
+
+regenerate-cgen: \
+    configure-cgen 
+	@: $(MAKE); $(unstage)
+	@[ -f ./cgen/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in cgen"; \
+	(cd $(HOST_SUBDIR)/cgen && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif cgen
+
 
 
 .PHONY: configure-dejagnu maybe-configure-dejagnu
@@ -8406,6 +8633,32 @@ maintainer-clean-dejagnu:
 
 @endif dejagnu
 
+.PHONY: maybe-regenerate-dejagnu regenerate-dejagnu
+maybe-regenerate-dejagnu:
+@if dejagnu
+maybe-regenerate-dejagnu: regenerate-dejagnu
+
+regenerate-dejagnu: \
+    configure-dejagnu 
+	@: $(MAKE); $(unstage)
+	@[ -f ./dejagnu/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in dejagnu"; \
+	(cd $(HOST_SUBDIR)/dejagnu && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif dejagnu
+
 
 
 .PHONY: configure-etc maybe-configure-etc
@@ -8874,6 +9127,16 @@ maintainer-clean-etc:
 
 @endif etc
 
+.PHONY: maybe-regenerate-etc regenerate-etc
+maybe-regenerate-etc:
+@if etc
+maybe-regenerate-etc: regenerate-etc
+
+# etc doesn't support regenerate.
+regenerate-etc:
+
+@endif etc
+
 
 
 .PHONY: configure-fastjar maybe-configure-fastjar
@@ -9345,6 +9608,32 @@ maintainer-clean-fastjar:
 
 @endif fastjar
 
+.PHONY: maybe-regenerate-fastjar regenerate-fastjar
+maybe-regenerate-fastjar:
+@if fastjar
+maybe-regenerate-fastjar: regenerate-fastjar
+
+regenerate-fastjar: \
+    configure-fastjar 
+	@: $(MAKE); $(unstage)
+	@[ -f ./fastjar/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in fastjar"; \
+	(cd $(HOST_SUBDIR)/fastjar && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif fastjar
+
 
 
 .PHONY: configure-fixincludes maybe-configure-fixincludes
@@ -10454,6 +10743,31 @@ maintainer-clean-fixincludes:
 
 @endif fixincludes
 
+.PHONY: maybe-regenerate-fixincludes regenerate-fixincludes
+maybe-regenerate-fixincludes:
+@if fixincludes
+maybe-regenerate-fixincludes: regenerate-fixincludes
+
+regenerate-fixincludes: \
+    configure-fixincludes 
+	@[ -f ./fixincludes/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in fixincludes"; \
+	(cd $(HOST_SUBDIR)/fixincludes && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif fixincludes
+
 
 
 .PHONY: configure-flex maybe-configure-flex
@@ -10925,6 +11239,32 @@ maintainer-clean-flex:
 
 @endif flex
 
+.PHONY: maybe-regenerate-flex regenerate-flex
+maybe-regenerate-flex:
+@if flex
+maybe-regenerate-flex: regenerate-flex
+
+regenerate-flex: \
+    configure-flex 
+	@: $(MAKE); $(unstage)
+	@[ -f ./flex/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in flex"; \
+	(cd $(HOST_SUBDIR)/flex && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif flex
+
 
 
 .PHONY: configure-gas maybe-configure-gas
@@ -12065,6 +12405,31 @@ maintainer-clean-gas:
 
 @endif gas
 
+.PHONY: maybe-regenerate-gas regenerate-gas
+maybe-regenerate-gas:
+@if gas
+maybe-regenerate-gas: regenerate-gas
+
+regenerate-gas: \
+    configure-gas 
+	@[ -f ./gas/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gas"; \
+	(cd $(HOST_SUBDIR)/gas && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gas
+
 
 
 .PHONY: configure-gcc maybe-configure-gcc
@@ -13214,6 +13579,31 @@ maintainer-clean-gcc:
 
 @endif gcc
 
+.PHONY: maybe-regenerate-gcc regenerate-gcc
+maybe-regenerate-gcc:
+@if gcc
+maybe-regenerate-gcc: regenerate-gcc
+
+regenerate-gcc: \
+    configure-gcc 
+	@[ -f ./gcc/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) $(EXTRA_GCC_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gcc"; \
+	(cd $(HOST_SUBDIR)/gcc && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gcc
+
 
 
 .PHONY: configure-gmp maybe-configure-gmp
@@ -14351,6 +14741,31 @@ maintainer-clean-gmp:
 
 @endif gmp
 
+.PHONY: maybe-regenerate-gmp regenerate-gmp
+maybe-regenerate-gmp:
+@if gmp
+maybe-regenerate-gmp: regenerate-gmp
+
+regenerate-gmp: \
+    configure-gmp 
+	@[ -f ./gmp/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gmp"; \
+	(cd $(HOST_SUBDIR)/gmp && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gmp
+
 
 
 .PHONY: configure-mpfr maybe-configure-mpfr
@@ -15488,6 +15903,31 @@ maintainer-clean-mpfr:
 
 @endif mpfr
 
+.PHONY: maybe-regenerate-mpfr regenerate-mpfr
+maybe-regenerate-mpfr:
+@if mpfr
+maybe-regenerate-mpfr: regenerate-mpfr
+
+regenerate-mpfr: \
+    configure-mpfr 
+	@[ -f ./mpfr/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in mpfr"; \
+	(cd $(HOST_SUBDIR)/mpfr && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif mpfr
+
 
 
 .PHONY: configure-mpc maybe-configure-mpc
@@ -16625,6 +17065,31 @@ maintainer-clean-mpc:
 
 @endif mpc
 
+.PHONY: maybe-regenerate-mpc regenerate-mpc
+maybe-regenerate-mpc:
+@if mpc
+maybe-regenerate-mpc: regenerate-mpc
+
+regenerate-mpc: \
+    configure-mpc 
+	@[ -f ./mpc/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in mpc"; \
+	(cd $(HOST_SUBDIR)/mpc && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif mpc
+
 
 
 .PHONY: configure-isl maybe-configure-isl
@@ -17762,6 +18227,31 @@ maintainer-clean-isl:
 
 @endif isl
 
+.PHONY: maybe-regenerate-isl regenerate-isl
+maybe-regenerate-isl:
+@if isl
+maybe-regenerate-isl: regenerate-isl
+
+regenerate-isl: \
+    configure-isl 
+	@[ -f ./isl/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) V=1; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in isl"; \
+	(cd $(HOST_SUBDIR)/isl && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif isl
+
 
 
 .PHONY: configure-gold maybe-configure-gold
@@ -18902,6 +19392,31 @@ maintainer-clean-gold:
 
 @endif gold
 
+.PHONY: maybe-regenerate-gold regenerate-gold
+maybe-regenerate-gold:
+@if gold
+maybe-regenerate-gold: regenerate-gold
+
+regenerate-gold: \
+    configure-gold 
+	@[ -f ./gold/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gold"; \
+	(cd $(HOST_SUBDIR)/gold && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gold
+
 
 
 .PHONY: configure-gprof maybe-configure-gprof
@@ -19370,6 +19885,32 @@ maintainer-clean-gprof:
 
 @endif gprof
 
+.PHONY: maybe-regenerate-gprof regenerate-gprof
+maybe-regenerate-gprof:
+@if gprof
+maybe-regenerate-gprof: regenerate-gprof
+
+regenerate-gprof: \
+    configure-gprof 
+	@: $(MAKE); $(unstage)
+	@[ -f ./gprof/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gprof"; \
+	(cd $(HOST_SUBDIR)/gprof && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gprof
+
 
 
 .PHONY: configure-gprofng maybe-configure-gprofng
@@ -19838,6 +20379,16 @@ maintainer-clean-gprofng:
 
 @endif gprofng
 
+.PHONY: maybe-regenerate-gprofng regenerate-gprofng
+maybe-regenerate-gprofng:
+@if gprofng
+maybe-regenerate-gprofng: regenerate-gprofng
+
+# gprofng doesn't support regenerate.
+regenerate-gprofng:
+
+@endif gprofng
+
 
 
 .PHONY: configure-gettext maybe-configure-gettext
@@ -20836,6 +21387,31 @@ maintainer-clean-gettext:
 
 @endif gettext
 
+.PHONY: maybe-regenerate-gettext regenerate-gettext
+maybe-regenerate-gettext:
+@if gettext
+maybe-regenerate-gettext: regenerate-gettext
+
+regenerate-gettext: \
+    configure-gettext 
+	@[ -f ./gettext/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gettext"; \
+	(cd $(HOST_SUBDIR)/gettext && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gettext
+
 
 
 .PHONY: configure-tcl maybe-configure-tcl
@@ -21289,6 +21865,32 @@ maintainer-clean-tcl:
 
 @endif tcl
 
+.PHONY: maybe-regenerate-tcl regenerate-tcl
+maybe-regenerate-tcl:
+@if tcl
+maybe-regenerate-tcl: regenerate-tcl
+
+regenerate-tcl: \
+    configure-tcl 
+	@: $(MAKE); $(unstage)
+	@[ -f ./tcl/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in tcl"; \
+	(cd $(HOST_SUBDIR)/tcl && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif tcl
+
 
 
 .PHONY: configure-itcl maybe-configure-itcl
@@ -21757,6 +22359,32 @@ maintainer-clean-itcl:
 
 @endif itcl
 
+.PHONY: maybe-regenerate-itcl regenerate-itcl
+maybe-regenerate-itcl:
+@if itcl
+maybe-regenerate-itcl: regenerate-itcl
+
+regenerate-itcl: \
+    configure-itcl 
+	@: $(MAKE); $(unstage)
+	@[ -f ./itcl/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in itcl"; \
+	(cd $(HOST_SUBDIR)/itcl && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif itcl
+
 
 
 .PHONY: configure-ld maybe-configure-ld
@@ -22897,6 +23525,31 @@ maintainer-clean-ld:
 
 @endif ld
 
+.PHONY: maybe-regenerate-ld regenerate-ld
+maybe-regenerate-ld:
+@if ld
+maybe-regenerate-ld: regenerate-ld
+
+regenerate-ld: \
+    configure-ld 
+	@[ -f ./ld/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in ld"; \
+	(cd $(HOST_SUBDIR)/ld && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif ld
+
 
 
 .PHONY: configure-libbacktrace maybe-configure-libbacktrace
@@ -24037,6 +24690,16 @@ maintainer-clean-libbacktrace:
 
 @endif libbacktrace
 
+.PHONY: maybe-regenerate-libbacktrace regenerate-libbacktrace
+maybe-regenerate-libbacktrace:
+@if libbacktrace
+maybe-regenerate-libbacktrace: regenerate-libbacktrace
+
+# libbacktrace doesn't support regenerate.
+regenerate-libbacktrace:
+
+@endif libbacktrace
+
 
 
 .PHONY: configure-libcpp maybe-configure-libcpp
@@ -25177,6 +25840,31 @@ maintainer-clean-libcpp:
 
 @endif libcpp
 
+.PHONY: maybe-regenerate-libcpp regenerate-libcpp
+maybe-regenerate-libcpp:
+@if libcpp
+maybe-regenerate-libcpp: regenerate-libcpp
+
+regenerate-libcpp: \
+    configure-libcpp 
+	@[ -f ./libcpp/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libcpp"; \
+	(cd $(HOST_SUBDIR)/libcpp && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libcpp
+
 
 
 .PHONY: configure-libcody maybe-configure-libcody
@@ -26166,6 +26854,31 @@ maintainer-clean-libcody:
 
 @endif libcody
 
+.PHONY: maybe-regenerate-libcody regenerate-libcody
+maybe-regenerate-libcody:
+@if libcody
+maybe-regenerate-libcody: regenerate-libcody
+
+regenerate-libcody: \
+    configure-libcody 
+	@[ -f ./libcody/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libcody"; \
+	(cd $(HOST_SUBDIR)/libcody && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libcody
+
 
 
 .PHONY: configure-libdecnumber maybe-configure-libdecnumber
@@ -27291,6 +28004,16 @@ maintainer-clean-libdecnumber:
 
 @endif libdecnumber
 
+.PHONY: maybe-regenerate-libdecnumber regenerate-libdecnumber
+maybe-regenerate-libdecnumber:
+@if libdecnumber
+maybe-regenerate-libdecnumber: regenerate-libdecnumber
+
+# libdecnumber doesn't support regenerate.
+regenerate-libdecnumber:
+
+@endif libdecnumber
+
 
 
 .PHONY: configure-libgui maybe-configure-libgui
@@ -27759,6 +28482,32 @@ maintainer-clean-libgui:
 
 @endif libgui
 
+.PHONY: maybe-regenerate-libgui regenerate-libgui
+maybe-regenerate-libgui:
+@if libgui
+maybe-regenerate-libgui: regenerate-libgui
+
+regenerate-libgui: \
+    configure-libgui 
+	@: $(MAKE); $(unstage)
+	@[ -f ./libgui/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libgui"; \
+	(cd $(HOST_SUBDIR)/libgui && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libgui
+
 
 
 .PHONY: configure-libiberty maybe-configure-libiberty
@@ -28908,6 +29657,16 @@ maintainer-clean-libiberty:
 
 @endif libiberty
 
+.PHONY: maybe-regenerate-libiberty regenerate-libiberty
+maybe-regenerate-libiberty:
+@if libiberty
+maybe-regenerate-libiberty: regenerate-libiberty
+
+# libiberty doesn't support regenerate.
+regenerate-libiberty:
+
+@endif libiberty
+
 
 
 .PHONY: configure-libiberty-linker-plugin maybe-configure-libiberty-linker-plugin
@@ -30057,6 +30816,31 @@ maintainer-clean-libiberty-linker-plugin:
 
 @endif libiberty-linker-plugin
 
+.PHONY: maybe-regenerate-libiberty-linker-plugin regenerate-libiberty-linker-plugin
+maybe-regenerate-libiberty-linker-plugin:
+@if libiberty-linker-plugin
+maybe-regenerate-libiberty-linker-plugin: regenerate-libiberty-linker-plugin
+
+regenerate-libiberty-linker-plugin: \
+    configure-libiberty-linker-plugin 
+	@[ -f ./libiberty-linker-plugin/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) @extra_linker_plugin_flags@; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libiberty-linker-plugin"; \
+	(cd $(HOST_SUBDIR)/libiberty-linker-plugin && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libiberty-linker-plugin
+
 
 
 .PHONY: configure-libiconv maybe-configure-libiconv
@@ -31101,6 +31885,31 @@ maintainer-clean-libiconv:
 
 @endif libiconv
 
+.PHONY: maybe-regenerate-libiconv regenerate-libiconv
+maybe-regenerate-libiconv:
+@if libiconv
+maybe-regenerate-libiconv: regenerate-libiconv
+
+regenerate-libiconv: \
+    configure-libiconv 
+	@[ -f ./libiconv/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libiconv"; \
+	(cd $(HOST_SUBDIR)/libiconv && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libiconv
+
 
 
 .PHONY: configure-m4 maybe-configure-m4
@@ -31569,6 +32378,32 @@ maintainer-clean-m4:
 
 @endif m4
 
+.PHONY: maybe-regenerate-m4 regenerate-m4
+maybe-regenerate-m4:
+@if m4
+maybe-regenerate-m4: regenerate-m4
+
+regenerate-m4: \
+    configure-m4 
+	@: $(MAKE); $(unstage)
+	@[ -f ./m4/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in m4"; \
+	(cd $(HOST_SUBDIR)/m4 && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif m4
+
 
 
 .PHONY: configure-readline maybe-configure-readline
@@ -32037,6 +32872,16 @@ maintainer-clean-readline:
 
 @endif readline
 
+.PHONY: maybe-regenerate-readline regenerate-readline
+maybe-regenerate-readline:
+@if readline
+maybe-regenerate-readline: regenerate-readline
+
+# readline doesn't support regenerate.
+regenerate-readline:
+
+@endif readline
+
 
 
 .PHONY: configure-sid maybe-configure-sid
@@ -32505,6 +33350,32 @@ maintainer-clean-sid:
 
 @endif sid
 
+.PHONY: maybe-regenerate-sid regenerate-sid
+maybe-regenerate-sid:
+@if sid
+maybe-regenerate-sid: regenerate-sid
+
+regenerate-sid: \
+    configure-sid 
+	@: $(MAKE); $(unstage)
+	@[ -f ./sid/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in sid"; \
+	(cd $(HOST_SUBDIR)/sid && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif sid
+
 
 
 .PHONY: configure-sim maybe-configure-sim
@@ -32973,6 +33844,16 @@ maintainer-clean-sim:
 
 @endif sim
 
+.PHONY: maybe-regenerate-sim regenerate-sim
+maybe-regenerate-sim:
+@if sim
+maybe-regenerate-sim: regenerate-sim
+
+# sim doesn't support regenerate.
+regenerate-sim:
+
+@endif sim
+
 
 
 .PHONY: configure-texinfo maybe-configure-texinfo
@@ -33429,6 +34310,32 @@ maintainer-clean-texinfo:
 
 @endif texinfo
 
+.PHONY: maybe-regenerate-texinfo regenerate-texinfo
+maybe-regenerate-texinfo:
+@if texinfo
+maybe-regenerate-texinfo: regenerate-texinfo
+
+regenerate-texinfo: \
+    configure-texinfo 
+	@: $(MAKE); $(unstage)
+	@[ -f ./texinfo/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in texinfo"; \
+	(cd $(HOST_SUBDIR)/texinfo && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif texinfo
+
 
 
 .PHONY: configure-zlib maybe-configure-zlib
@@ -34560,6 +35467,16 @@ maintainer-clean-zlib:
 
 @endif zlib
 
+.PHONY: maybe-regenerate-zlib regenerate-zlib
+maybe-regenerate-zlib:
+@if zlib
+maybe-regenerate-zlib: regenerate-zlib
+
+# zlib doesn't support regenerate.
+regenerate-zlib:
+
+@endif zlib
+
 
 
 .PHONY: configure-gnulib maybe-configure-gnulib
@@ -35028,6 +35945,16 @@ maintainer-clean-gnulib:
 
 @endif gnulib
 
+.PHONY: maybe-regenerate-gnulib regenerate-gnulib
+maybe-regenerate-gnulib:
+@if gnulib
+maybe-regenerate-gnulib: regenerate-gnulib
+
+# gnulib doesn't support regenerate.
+regenerate-gnulib:
+
+@endif gnulib
+
 
 
 .PHONY: configure-gdbsupport maybe-configure-gdbsupport
@@ -35496,6 +36423,16 @@ maintainer-clean-gdbsupport:
 
 @endif gdbsupport
 
+.PHONY: maybe-regenerate-gdbsupport regenerate-gdbsupport
+maybe-regenerate-gdbsupport:
+@if gdbsupport
+maybe-regenerate-gdbsupport: regenerate-gdbsupport
+
+# gdbsupport doesn't support regenerate.
+regenerate-gdbsupport:
+
+@endif gdbsupport
+
 
 
 .PHONY: configure-gdbserver maybe-configure-gdbserver
@@ -35964,6 +36901,16 @@ maintainer-clean-gdbserver:
 
 @endif gdbserver
 
+.PHONY: maybe-regenerate-gdbserver regenerate-gdbserver
+maybe-regenerate-gdbserver:
+@if gdbserver
+maybe-regenerate-gdbserver: regenerate-gdbserver
+
+# gdbserver doesn't support regenerate.
+regenerate-gdbserver:
+
+@endif gdbserver
+
 
 
 .PHONY: configure-gdb maybe-configure-gdb
@@ -36432,6 +37379,32 @@ maintainer-clean-gdb:
 
 @endif gdb
 
+.PHONY: maybe-regenerate-gdb regenerate-gdb
+maybe-regenerate-gdb:
+@if gdb
+maybe-regenerate-gdb: regenerate-gdb
+
+regenerate-gdb: \
+    configure-gdb 
+	@: $(MAKE); $(unstage)
+	@[ -f ./gdb/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gdb"; \
+	(cd $(HOST_SUBDIR)/gdb && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gdb
+
 
 
 .PHONY: configure-expect maybe-configure-expect
@@ -36900,6 +37873,32 @@ maintainer-clean-expect:
 
 @endif expect
 
+.PHONY: maybe-regenerate-expect regenerate-expect
+maybe-regenerate-expect:
+@if expect
+maybe-regenerate-expect: regenerate-expect
+
+regenerate-expect: \
+    configure-expect 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expect/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in expect"; \
+	(cd $(HOST_SUBDIR)/expect && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif expect
+
 
 
 .PHONY: configure-guile maybe-configure-guile
@@ -37368,6 +38367,32 @@ maintainer-clean-guile:
 
 @endif guile
 
+.PHONY: maybe-regenerate-guile regenerate-guile
+maybe-regenerate-guile:
+@if guile
+maybe-regenerate-guile: regenerate-guile
+
+regenerate-guile: \
+    configure-guile 
+	@: $(MAKE); $(unstage)
+	@[ -f ./guile/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in guile"; \
+	(cd $(HOST_SUBDIR)/guile && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif guile
+
 
 
 .PHONY: configure-tk maybe-configure-tk
@@ -37836,6 +38861,32 @@ maintainer-clean-tk:
 
 @endif tk
 
+.PHONY: maybe-regenerate-tk regenerate-tk
+maybe-regenerate-tk:
+@if tk
+maybe-regenerate-tk: regenerate-tk
+
+regenerate-tk: \
+    configure-tk 
+	@: $(MAKE); $(unstage)
+	@[ -f ./tk/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in tk"; \
+	(cd $(HOST_SUBDIR)/tk && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif tk
+
 
 
 .PHONY: configure-libtermcap maybe-configure-libtermcap
@@ -38238,6 +39289,32 @@ maintainer-clean-libtermcap:
 
 @endif libtermcap
 
+.PHONY: maybe-regenerate-libtermcap regenerate-libtermcap
+maybe-regenerate-libtermcap:
+@if libtermcap
+maybe-regenerate-libtermcap: regenerate-libtermcap
+
+regenerate-libtermcap: \
+    configure-libtermcap 
+	@: $(MAKE); $(unstage)
+	@[ -f ./libtermcap/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libtermcap"; \
+	(cd $(HOST_SUBDIR)/libtermcap && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libtermcap
+
 
 
 .PHONY: configure-utils maybe-configure-utils
@@ -38700,6 +39777,32 @@ maintainer-clean-utils:
 
 @endif utils
 
+.PHONY: maybe-regenerate-utils regenerate-utils
+maybe-regenerate-utils:
+@if utils
+maybe-regenerate-utils: regenerate-utils
+
+regenerate-utils: \
+    configure-utils 
+	@: $(MAKE); $(unstage)
+	@[ -f ./utils/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in utils"; \
+	(cd $(HOST_SUBDIR)/utils && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif utils
+
 
 
 .PHONY: configure-c++tools maybe-configure-c++tools
@@ -39152,6 +40255,32 @@ maintainer-clean-c++tools:
 
 @endif c++tools
 
+.PHONY: maybe-regenerate-c++tools regenerate-c++tools
+maybe-regenerate-c++tools:
+@if c++tools
+maybe-regenerate-c++tools: regenerate-c++tools
+
+regenerate-c++tools: \
+    configure-c++tools 
+	@: $(MAKE); $(unstage)
+	@[ -f ./c++tools/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in c++tools"; \
+	(cd $(HOST_SUBDIR)/c++tools && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif c++tools
+
 
 
 .PHONY: configure-gnattools maybe-configure-gnattools
@@ -39620,6 +40749,32 @@ maintainer-clean-gnattools:
 
 @endif gnattools
 
+.PHONY: maybe-regenerate-gnattools regenerate-gnattools
+maybe-regenerate-gnattools:
+@if gnattools
+maybe-regenerate-gnattools: regenerate-gnattools
+
+regenerate-gnattools: \
+    configure-gnattools 
+	@: $(MAKE); $(unstage)
+	@[ -f ./gnattools/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gnattools"; \
+	(cd $(HOST_SUBDIR)/gnattools && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gnattools
+
 
 
 .PHONY: configure-lto-plugin maybe-configure-lto-plugin
@@ -40769,6 +41924,31 @@ maintainer-clean-lto-plugin:
 
 @endif lto-plugin
 
+.PHONY: maybe-regenerate-lto-plugin regenerate-lto-plugin
+maybe-regenerate-lto-plugin:
+@if lto-plugin
+maybe-regenerate-lto-plugin: regenerate-lto-plugin
+
+regenerate-lto-plugin: \
+    configure-lto-plugin 
+	@[ -f ./lto-plugin/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) @extra_linker_plugin_flags@; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in lto-plugin"; \
+	(cd $(HOST_SUBDIR)/lto-plugin && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif lto-plugin
+
 
 
 .PHONY: configure-libcc1 maybe-configure-libcc1
@@ -41237,6 +42417,32 @@ maintainer-clean-libcc1:
 
 @endif libcc1
 
+.PHONY: maybe-regenerate-libcc1 regenerate-libcc1
+maybe-regenerate-libcc1:
+@if libcc1
+maybe-regenerate-libcc1: regenerate-libcc1
+
+regenerate-libcc1: \
+    configure-libcc1 
+	@: $(MAKE); $(unstage)
+	@[ -f ./libcc1/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libcc1"; \
+	(cd $(HOST_SUBDIR)/libcc1 && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libcc1
+
 
 
 .PHONY: configure-gotools maybe-configure-gotools
@@ -41705,6 +42911,32 @@ maintainer-clean-gotools:
 
 @endif gotools
 
+.PHONY: maybe-regenerate-gotools regenerate-gotools
+maybe-regenerate-gotools:
+@if gotools
+maybe-regenerate-gotools: regenerate-gotools
+
+regenerate-gotools: \
+    configure-gotools 
+	@: $(MAKE); $(unstage)
+	@[ -f ./gotools/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in gotools"; \
+	(cd $(HOST_SUBDIR)/gotools && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif gotools
+
 
 
 .PHONY: configure-libctf maybe-configure-libctf
@@ -42845,6 +44077,16 @@ maintainer-clean-libctf:
 
 @endif libctf
 
+.PHONY: maybe-regenerate-libctf regenerate-libctf
+maybe-regenerate-libctf:
+@if libctf
+maybe-regenerate-libctf: regenerate-libctf
+
+# libctf doesn't support regenerate.
+regenerate-libctf:
+
+@endif libctf
+
 
 
 .PHONY: configure-libsframe maybe-configure-libsframe
@@ -43985,6 +45227,16 @@ maintainer-clean-libsframe:
 
 @endif libsframe
 
+.PHONY: maybe-regenerate-libsframe regenerate-libsframe
+maybe-regenerate-libsframe:
+@if libsframe
+maybe-regenerate-libsframe: regenerate-libsframe
+
+# libsframe doesn't support regenerate.
+regenerate-libsframe:
+
+@endif libsframe
+
 
 
 .PHONY: configure-libgrust maybe-configure-libgrust
@@ -44453,6 +45705,32 @@ maintainer-clean-libgrust:
 
 @endif libgrust
 
+.PHONY: maybe-regenerate-libgrust regenerate-libgrust
+maybe-regenerate-libgrust:
+@if libgrust
+maybe-regenerate-libgrust: regenerate-libgrust
+
+regenerate-libgrust: \
+    configure-libgrust 
+	@: $(MAKE); $(unstage)
+	@[ -f ./libgrust/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing regenerate in libgrust"; \
+	(cd $(HOST_SUBDIR)/libgrust && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	          regenerate) \
+	  || exit 1
+
+@endif libgrust
+
 
 
 # ---------------------------------------
@@ -45728,6 +47006,32 @@ maintainer-clean-target-libstdc++-v3:
 
 @endif target-libstdc++-v3
 
+.PHONY: maybe-regenerate-target-libstdc++-v3 regenerate-target-libstdc++-v3
+maybe-regenerate-target-libstdc++-v3:
+@if target-libstdc++-v3
+maybe-regenerate-target-libstdc++-v3: regenerate-target-libstdc++-v3
+
+regenerate-target-libstdc++-v3: \
+    configure-target-libstdc++-v3 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libstdc++-v3/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(RAW_CXX_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libstdc++-v3"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libstdc++-v3 && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libstdc++-v3
+
 
 
 
@@ -46998,6 +48302,32 @@ maintainer-clean-target-libsanitizer:
 
 @endif target-libsanitizer
 
+.PHONY: maybe-regenerate-target-libsanitizer regenerate-target-libsanitizer
+maybe-regenerate-target-libsanitizer:
+@if target-libsanitizer
+maybe-regenerate-target-libsanitizer: regenerate-target-libsanitizer
+
+regenerate-target-libsanitizer: \
+    configure-target-libsanitizer 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libsanitizer/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(RAW_CXX_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libsanitizer"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libsanitizer && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libsanitizer
+
 
 
 
@@ -48268,6 +49598,32 @@ maintainer-clean-target-libvtv:
 
 @endif target-libvtv
 
+.PHONY: maybe-regenerate-target-libvtv regenerate-target-libvtv
+maybe-regenerate-target-libvtv:
+@if target-libvtv
+maybe-regenerate-target-libvtv: regenerate-target-libvtv
+
+regenerate-target-libvtv: \
+    configure-target-libvtv 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(RAW_CXX_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libvtv"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libvtv && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libvtv
+
 
 
 
@@ -48753,6 +50109,32 @@ maintainer-clean-target-libssp:
 
 @endif target-libssp
 
+.PHONY: maybe-regenerate-target-libssp regenerate-target-libssp
+maybe-regenerate-target-libssp:
+@if target-libssp
+maybe-regenerate-target-libssp: regenerate-target-libssp
+
+regenerate-target-libssp: \
+    configure-target-libssp 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libssp/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libssp"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libssp && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libssp
+
 
 
 
@@ -49238,6 +50620,32 @@ maintainer-clean-target-newlib:
 
 @endif target-newlib
 
+.PHONY: maybe-regenerate-target-newlib regenerate-target-newlib
+maybe-regenerate-target-newlib:
+@if target-newlib
+maybe-regenerate-target-newlib: regenerate-target-newlib
+
+regenerate-target-newlib: \
+    configure-target-newlib 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/newlib/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/newlib"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/newlib && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-newlib
+
 
 
 
@@ -50470,6 +51878,32 @@ maintainer-clean-target-libgcc:
 
 @endif target-libgcc
 
+.PHONY: maybe-regenerate-target-libgcc regenerate-target-libgcc
+maybe-regenerate-target-libgcc:
+@if target-libgcc
+maybe-regenerate-target-libgcc: regenerate-target-libgcc
+
+regenerate-target-libgcc: \
+    configure-target-libgcc 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libgcc/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libgcc"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libgcc && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libgcc
+
 
 
 
@@ -51740,6 +53174,32 @@ maintainer-clean-target-libbacktrace:
 
 @endif target-libbacktrace
 
+.PHONY: maybe-regenerate-target-libbacktrace regenerate-target-libbacktrace
+maybe-regenerate-target-libbacktrace:
+@if target-libbacktrace
+maybe-regenerate-target-libbacktrace: regenerate-target-libbacktrace
+
+regenerate-target-libbacktrace: \
+    configure-target-libbacktrace 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libbacktrace"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libbacktrace && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libbacktrace
+
 
 
 
@@ -52225,6 +53685,32 @@ maintainer-clean-target-libquadmath:
 
 @endif target-libquadmath
 
+.PHONY: maybe-regenerate-target-libquadmath regenerate-target-libquadmath
+maybe-regenerate-target-libquadmath:
+@if target-libquadmath
+maybe-regenerate-target-libquadmath: regenerate-target-libquadmath
+
+regenerate-target-libquadmath: \
+    configure-target-libquadmath 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libquadmath/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libquadmath"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libquadmath && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libquadmath
+
 
 
 
@@ -52710,6 +54196,32 @@ maintainer-clean-target-libgfortran:
 
 @endif target-libgfortran
 
+.PHONY: maybe-regenerate-target-libgfortran regenerate-target-libgfortran
+maybe-regenerate-target-libgfortran:
+@if target-libgfortran
+maybe-regenerate-target-libgfortran: regenerate-target-libgfortran
+
+regenerate-target-libgfortran: \
+    configure-target-libgfortran 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libgfortran"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libgfortran && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libgfortran
+
 
 
 
@@ -53162,6 +54674,32 @@ maintainer-clean-target-libobjc:
 
 @endif target-libobjc
 
+.PHONY: maybe-regenerate-target-libobjc regenerate-target-libobjc
+maybe-regenerate-target-libobjc:
+@if target-libobjc
+maybe-regenerate-target-libobjc: regenerate-target-libobjc
+
+regenerate-target-libobjc: \
+    configure-target-libobjc 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libobjc/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libobjc"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libobjc && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libobjc
+
 
 
 
@@ -53647,6 +55185,32 @@ maintainer-clean-target-libgo:
 
 @endif target-libgo
 
+.PHONY: maybe-regenerate-target-libgo regenerate-target-libgo
+maybe-regenerate-target-libgo:
+@if target-libgo
+maybe-regenerate-target-libgo: regenerate-target-libgo
+
+regenerate-target-libgo: \
+    configure-target-libgo 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libgo/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libgo"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libgo && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libgo
+
 
 
 
@@ -54917,6 +56481,32 @@ maintainer-clean-target-libphobos:
 
 @endif target-libphobos
 
+.PHONY: maybe-regenerate-target-libphobos regenerate-target-libphobos
+maybe-regenerate-target-libphobos:
+@if target-libphobos
+maybe-regenerate-target-libphobos: regenerate-target-libphobos
+
+regenerate-target-libphobos: \
+    configure-target-libphobos 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libphobos"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libphobos && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libphobos
+
 
 
 
@@ -55337,6 +56927,32 @@ maintainer-clean-target-libtermcap:
 
 @endif target-libtermcap
 
+.PHONY: maybe-regenerate-target-libtermcap regenerate-target-libtermcap
+maybe-regenerate-target-libtermcap:
+@if target-libtermcap
+maybe-regenerate-target-libtermcap: regenerate-target-libtermcap
+
+regenerate-target-libtermcap: \
+    configure-target-libtermcap 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libtermcap/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libtermcap"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libtermcap && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libtermcap
+
 
 
 
@@ -55822,6 +57438,32 @@ maintainer-clean-target-winsup:
 
 @endif target-winsup
 
+.PHONY: maybe-regenerate-target-winsup regenerate-target-winsup
+maybe-regenerate-target-winsup:
+@if target-winsup
+maybe-regenerate-target-winsup: regenerate-target-winsup
+
+regenerate-target-winsup: \
+    configure-target-winsup 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/winsup/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/winsup"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/winsup && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-winsup
+
 
 
 
@@ -56302,6 +57944,32 @@ maintainer-clean-target-libgloss:
 
 @endif target-libgloss
 
+.PHONY: maybe-regenerate-target-libgloss regenerate-target-libgloss
+maybe-regenerate-target-libgloss:
+@if target-libgloss
+maybe-regenerate-target-libgloss: regenerate-target-libgloss
+
+regenerate-target-libgloss: \
+    configure-target-libgloss 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libgloss/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libgloss"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libgloss && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libgloss
+
 
 
 
@@ -56777,6 +58445,32 @@ maintainer-clean-target-libffi:
 
 @endif target-libffi
 
+.PHONY: maybe-regenerate-target-libffi regenerate-target-libffi
+maybe-regenerate-target-libffi:
+@if target-libffi
+maybe-regenerate-target-libffi: regenerate-target-libffi
+
+regenerate-target-libffi: \
+    configure-target-libffi 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libffi/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libffi"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libffi && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libffi
+
 
 
 
@@ -58047,6 +59741,32 @@ maintainer-clean-target-zlib:
 
 @endif target-zlib
 
+.PHONY: maybe-regenerate-target-zlib regenerate-target-zlib
+maybe-regenerate-target-zlib:
+@if target-zlib
+maybe-regenerate-target-zlib: regenerate-target-zlib
+
+regenerate-target-zlib: \
+    configure-target-zlib 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/zlib/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/zlib"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/zlib && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-zlib
+
 
 
 
@@ -58532,6 +60252,32 @@ maintainer-clean-target-rda:
 
 @endif target-rda
 
+.PHONY: maybe-regenerate-target-rda regenerate-target-rda
+maybe-regenerate-target-rda:
+@if target-rda
+maybe-regenerate-target-rda: regenerate-target-rda
+
+regenerate-target-rda: \
+    configure-target-rda 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/rda/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/rda"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/rda && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-rda
+
 
 
 
@@ -59017,6 +60763,32 @@ maintainer-clean-target-libada:
 
 @endif target-libada
 
+.PHONY: maybe-regenerate-target-libada regenerate-target-libada
+maybe-regenerate-target-libada:
+@if target-libada
+maybe-regenerate-target-libada: regenerate-target-libada
+
+regenerate-target-libada: \
+    configure-target-libada 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libada/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libada"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libada && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libada
+
 
 
 
@@ -59502,6 +61274,32 @@ maintainer-clean-target-libgm2:
 
 @endif target-libgm2
 
+.PHONY: maybe-regenerate-target-libgm2 regenerate-target-libgm2
+maybe-regenerate-target-libgm2:
+@if target-libgm2
+maybe-regenerate-target-libgm2: regenerate-target-libgm2
+
+regenerate-target-libgm2: \
+    configure-target-libgm2 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libgm2/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libgm2"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libgm2 && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libgm2
+
 
 
 
@@ -60772,6 +62570,32 @@ maintainer-clean-target-libgomp:
 
 @endif target-libgomp
 
+.PHONY: maybe-regenerate-target-libgomp regenerate-target-libgomp
+maybe-regenerate-target-libgomp:
+@if target-libgomp
+maybe-regenerate-target-libgomp: regenerate-target-libgomp
+
+regenerate-target-libgomp: \
+    configure-target-libgomp 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libgomp"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libgomp && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libgomp
+
 
 
 
@@ -61257,6 +63081,32 @@ maintainer-clean-target-libitm:
 
 @endif target-libitm
 
+.PHONY: maybe-regenerate-target-libitm regenerate-target-libitm
+maybe-regenerate-target-libitm:
+@if target-libitm
+maybe-regenerate-target-libitm: regenerate-target-libitm
+
+regenerate-target-libitm: \
+    configure-target-libitm 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libitm/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libitm"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libitm && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libitm
+
 
 
 
@@ -62527,6 +64377,32 @@ maintainer-clean-target-libatomic:
 
 @endif target-libatomic
 
+.PHONY: maybe-regenerate-target-libatomic regenerate-target-libatomic
+maybe-regenerate-target-libatomic:
+@if target-libatomic
+maybe-regenerate-target-libatomic: regenerate-target-libatomic
+
+regenerate-target-libatomic: \
+    configure-target-libatomic 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libatomic"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libatomic && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libatomic
+
 
 
 
@@ -63012,6 +64888,32 @@ maintainer-clean-target-libgrust:
 
 @endif target-libgrust
 
+.PHONY: maybe-regenerate-target-libgrust regenerate-target-libgrust
+maybe-regenerate-target-libgrust:
+@if target-libgrust
+maybe-regenerate-target-libgrust: regenerate-target-libgrust
+
+regenerate-target-libgrust: \
+    configure-target-libgrust 
+	@: $(MAKE); $(unstage)
+	@[ -f $(TARGET_SUBDIR)/libgrust/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(NORMAL_TARGET_EXPORTS) \
+	echo "Doing regenerate in $(TARGET_SUBDIR)/libgrust"; \
+	for flag in $(EXTRA_TARGET_FLAGS); do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	(cd $(TARGET_SUBDIR)/libgrust && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+	           regenerate) \
+	  || exit 1
+
+@endif target-libgrust
+
 
 
 @if target-libgomp
diff --git a/Makefile.tpl b/Makefile.tpl
index adbcbdd1d57..2241bf231d8 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -1055,6 +1055,13 @@ clang-format: $(srcdir)/.clang-format
 
 .PHONY: clang-format
 
+.PHONY: regenerate
+regenerate:
+	@: $(MAKE); $(unstage)
+	@r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(MAKE) $(RECURSE_FLAGS_TO_PASS) regenerate-host regenerate-target
+
 # Installation targets.
 
 .PHONY: install uninstall
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 4f67b59585d..cbd37b8043f 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -748,6 +748,7 @@ $(BFD32_LIBS) \
 SRC_POTFILES = $(SOURCE_CFILES) $(SOURCE_HFILES)
 BLD_POTFILES = $(BUILD_CFILES) $(BUILD_HFILES)
 
+regenerate: po/SRC-POTFILES.in po/BLD-POTFILES.in $(srcdir)/bfd-in2.h $(srcdir)/libbfd.h $(srcdir)/libcoff.h
 po/SRC-POTFILES.in: @MAINT@ Makefile
 	for file in $(SRC_POTFILES); do echo $$file; done \
 	  | LC_ALL=C sort | uniq > tmp.src \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index faaa0c424b8..9db3a283420 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -2295,6 +2295,7 @@ $(BFD32_LIBS) \
  $(BFD64_BACKENDS) \
  $(OPTIONAL_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
 
+regenerate: po/SRC-POTFILES.in po/BLD-POTFILES.in $(srcdir)/bfd-in2.h $(srcdir)/libbfd.h $(srcdir)/libcoff.h
 po/SRC-POTFILES.in: @MAINT@ Makefile
 	for file in $(SRC_POTFILES); do echo $$file; done \
 	  | LC_ALL=C sort | uniq > tmp.src \
diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index ad571b60546..c4879903795 100644
--- a/binutils/Makefile.am
+++ b/binutils/Makefile.am
@@ -181,6 +181,7 @@ LIBSFRAME = ../libsframe/libsframe.la
 LIBIBERTY = ../libiberty/libiberty.a
 
 POTFILES = $(CFILES) $(DEBUG_SRCS) $(HFILES)
+regenerate: po/POTFILES.in
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index 842a6d99b54..767bca98ccb 100644
--- a/binutils/Makefile.in
+++ b/binutils/Makefile.in
@@ -1827,6 +1827,7 @@ uninstall-man: uninstall-man1
 
 .PRECIOUS: Makefile
 
+regenerate: po/POTFILES.in
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 37ca0952f7e..3961b3a9e61 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -376,6 +376,7 @@ POTFILES = $(MULTI_CFILES) $(CONFIG_ATOF_CFILES) \
 	$(TARG_ENV_HFILES) $(TARG_ENV_CFILES) $(OBJ_FORMAT_HFILES) \
 	$(OBJ_FORMAT_CFILES) $(TARGET_CPU_HFILES) $(TARGET_CPU_CFILES) \
 	$(TARGET_EXTRA_FILES) $(HFILES) $(CFILES)
+regenerate: po/POTFILES.in $(srcdir)/../opcodes/i386-init.h $(srcdir)/../opcodes/i386-tbl.h $(srcdir)/../opcodes/i386-mnem.h
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/gas/Makefile.in b/gas/Makefile.in
index bc25765cb5b..bfc863f9b7c 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -2070,6 +2070,7 @@ uninstall-man: uninstall-man1
 
 .PRECIOUS: Makefile
 
+regenerate: po/POTFILES.in $(srcdir)/../opcodes/i386-init.h $(srcdir)/../opcodes/i386-tbl.h $(srcdir)/../opcodes/i386-mnem.h
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 0e0f19c40c9..40732cb2227 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2384,6 +2384,7 @@ doc/gdb.dvi:
 doc/gdb.info:
 	cd doc; $(MAKE) gdb.info $(FLAGS_TO_PASS)
 
+regenerate: $(srcdir)/copying.c
 # Make copying.c from COPYING
 $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
 	awk -f $(srcdir)/copying.awk \
diff --git a/gold/Makefile.am b/gold/Makefile.am
index ddd6a007438..9b655d4ba2b 100644
--- a/gold/Makefile.am
+++ b/gold/Makefile.am
@@ -244,7 +244,7 @@ install-exec-local: ld-new$(EXEEXT)
 	fi
 
 POTFILES= $(CCFILES) $(HFILES) $(TARGETSOURCES)
-
+regenerate: po/POTFILES.in
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/gold/Makefile.in b/gold/Makefile.in
index 1e6b9c77fc1..e0ba9fa4748 100644
--- a/gold/Makefile.in
+++ b/gold/Makefile.in
@@ -1627,7 +1627,7 @@ install-exec-local: ld-new$(EXEEXT)
 	    || $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \
 	  fi; \
 	fi
-
+regenerate: po/POTFILES.in
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/gprof/Makefile.am b/gprof/Makefile.am
index 0b2b59915a9..ec859826e40 100644
--- a/gprof/Makefile.am
+++ b/gprof/Makefile.am
@@ -70,6 +70,7 @@ CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/development.sh
 	    FILE=$*.m $<
 
 POTFILES = $(sources) $(noinst_HEADERS)
+regenerate: po/POTFILES.in
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/gprof/Makefile.in b/gprof/Makefile.in
index a7398231030..979b2a0419b 100644
--- a/gprof/Makefile.in
+++ b/gprof/Makefile.in
@@ -1190,6 +1190,7 @@ diststuff: $(BUILT_SOURCES) info $(man_MANS)
 	$(AM_V_GEN)awk -f $(srcdir)/gen-c-prog.awk > $@ \
 	    FUNCTION=`(echo $*|sed -e 's,.*/,,g' -e 's/_bl//')`_blurb \
 	    FILE=$*.m $<
+regenerate: po/POTFILES.in
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/ld/Makefile.am b/ld/Makefile.am
index f9ee05b1400..421b703b8b0 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -550,6 +550,7 @@ endif
 SRC_POTFILES = $(CFILES) $(HFILES)
 BLD_POTFILES = $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES)
 
+regenerate: po/SRC-POTFILES.in po/BLD-POTFILES.in
 po/SRC-POTFILES.in: @MAINT@ Makefile
 	for f in $(SRC_POTFILES); do echo $$f; done | LC_ALL=C sort > $@-tmp \
 	  && mv $@-tmp $(srcdir)/po/SRC-POTFILES.in
diff --git a/ld/Makefile.in b/ld/Makefile.in
index abb0565718f..4bf60799249 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -2307,6 +2307,7 @@ deffilep.@OBJEXT@: deffilep.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC)$(COMPILE) -c `test -f deffilep.c || echo $(srcdir)/`deffilep.c $(NO_WERROR)
 
+regenerate: po/SRC-POTFILES.in po/BLD-POTFILES.in
 po/SRC-POTFILES.in: @MAINT@ Makefile
 	for f in $(SRC_POTFILES); do echo $$f; done | LC_ALL=C sort > $@-tmp \
 	  && mv $@-tmp $(srcdir)/po/SRC-POTFILES.in
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index a173c8e6f36..162cc531153 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -324,6 +324,8 @@ stamp-lib: libopcodes.la
 libopcodes.a: stamp-lib ; @true
 
 POTFILES = $(HFILES) $(LIBOPCODES_CFILES)
+regenerate: po/POTFILES.in $(srcdir)/aarch64-asm-2.c $(srcdir)/aarch64-dis-2.c $(srcdir)/aarch64-opc-2.c $(srcdir)/i386-tbl.h $(srcdir)/i386-init.h $(srcdir)/i386-mnem.h $(srcdir)/ia64-asmtab.c $(srcdir)/msp430-decode.c $(srcdir)/rl78-decode.c $(srcdir)/rx-decode.c $(srcdir)/z8k-opc.h
+
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
index 57aaed26da8..b768dafeab6 100644
--- a/opcodes/Makefile.in
+++ b/opcodes/Makefile.in
@@ -1370,6 +1370,8 @@ stamp-lib: libopcodes.la
 	touch stamp-lib
 
 libopcodes.a: stamp-lib ; @true
+regenerate: po/POTFILES.in $(srcdir)/aarch64-asm-2.c $(srcdir)/aarch64-dis-2.c $(srcdir)/aarch64-opc-2.c $(srcdir)/i386-tbl.h $(srcdir)/i386-init.h $(srcdir)/i386-mnem.h $(srcdir)/ia64-asmtab.c $(srcdir)/msp430-decode.c $(srcdir)/rl78-decode.c $(srcdir)/rx-decode.c $(srcdir)/z8k-opc.h
+
 po/POTFILES.in: @MAINT@ Makefile
 	for f in $(POTFILES); do echo $$f; done | LC_ALL=C sort > tmp \
 	  && mv tmp $(srcdir)/po/POTFILES.in
-- 
2.34.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-13  8:02 [RFC] add regenerate Makefile target Christophe Lyon
@ 2024-03-14 18:10 ` Simon Marchi
  2024-03-15  8:50   ` Christophe Lyon
  0 siblings, 1 reply; 21+ messages in thread
From: Simon Marchi @ 2024-03-14 18:10 UTC (permalink / raw)
  To: Christophe Lyon, binutils, gdb, gcc



On 2024-03-13 04:02, Christophe Lyon via Gdb wrote:
> Hi!
> 
> After recent discussions on IRC and on the lists about maintainer-mode
> and various problems with auto-generated source files, I've written
> this small prototype.
> 
> Based on those discussions, I assumed that people generally want to
> update autotools files using a script similar to autoregen.py, which
> takes care of running aclocal, autoheader, automake and autoconf as
> appropriate.
> 
> What is currently missing is a "simple" way of regenerating other
> files, which happens normally with --enable-maintainer-mode (which is
> reportedly broken).  This patch as a "regenerate" Makefile target
> which can be called to update those files, provided
> --enable-maintainer-mode is used.
> 
> I tried this approach with the following workflow for binutils/gdb:
> - run autoregen.py in srcdir
> - cd builddir
> - configure --enable-maintainer-mode 
> - make all-bfd all-libiberty regenerate -j1
> - for gdb: make all -C gdb/data-directory -j1
> - make all -jXXX
> 
> Making 'all' in bfd and libiberty is needed by some XXX-gen host
> programs in opcodes.
> 
> The advantage (for instance for CI) is that we can regenerate files at
> -j1, thus avoiding the existing race conditions, and build the rest
> with -j XXX.
> 
> Among drawbacks:
> - most sub-components use Makefile.am, but gdb does not: this may make
>   maintenance more complex (different rules for different projects)
> - maintaining such ad-hoc "regenerate" rules would require special
>   attention from maintainers/reviewers
> - dependency on -all-bfd and all-libiberty is probably not fully
>    intuitive, but should not be a problem if the "regenerate" rules
>    are used after a full build for instance
> 
> Of course Makefile.def/Makefile.tpl would need further cleanup as I
> didn't try to take gcc into account is this patch.
> 
> Thoughts?

My first thought it: why is it a Makefile target, instead of some script
on the side (like autoregen.sh).  It would be nice / useful to be
able to it without configuring / building anything.  For instance, the
autoregen buildbot job could run it without configuring anything.
Ideally, the buildbot wouldn't maintain its own autoregen.py file on the
side, it would just use whatever is in the repo.

Looking at the rule to re-generate copying.c in gdb for instance:

    # Make copying.c from COPYING
    $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
           awk -f $(srcdir)/copying.awk \
               < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp
           mv $(srcdir)/copying.tmp $(srcdir)/copying.c

There is nothing in this code that requires having configured the source
tree.  This code could for instance be moved to some
generate-copying-c.sh script.  generate-copying-c.sh could be called by
an hypothetical autoregen.sh script, as well as the copying.c Makefile
target, if we want to continue supporting the maintainer mode.

Much like your regenerate targets, an autoregen.sh script in a given
directory would be responsible to re-generate all the files in this
directory that are generated and checked in git.  It would also be
responsible to call any autoregen.sh file in subdirectories.

There's just the issue of files that are generated using tools that are
compiled.  When experimenting with maintainer mode the other day, I
stumbled on the opcodes/i386-gen, for instance.  I don't have a good
solution to that, except to rewrite these tools in a scripting language
like Python.

Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-14 18:10 ` Simon Marchi
@ 2024-03-15  8:50   ` Christophe Lyon
  2024-03-15 14:13     ` Eric Gallager
                       ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Christophe Lyon @ 2024-03-15  8:50 UTC (permalink / raw)
  To: Simon Marchi; +Cc: binutils, gdb, gcc

On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
>
>
>
> On 2024-03-13 04:02, Christophe Lyon via Gdb wrote:
> > Hi!
> >
> > After recent discussions on IRC and on the lists about maintainer-mode
> > and various problems with auto-generated source files, I've written
> > this small prototype.
> >
> > Based on those discussions, I assumed that people generally want to
> > update autotools files using a script similar to autoregen.py, which
> > takes care of running aclocal, autoheader, automake and autoconf as
> > appropriate.
> >
> > What is currently missing is a "simple" way of regenerating other
> > files, which happens normally with --enable-maintainer-mode (which is
> > reportedly broken).  This patch as a "regenerate" Makefile target
> > which can be called to update those files, provided
> > --enable-maintainer-mode is used.
> >
> > I tried this approach with the following workflow for binutils/gdb:
> > - run autoregen.py in srcdir
> > - cd builddir
> > - configure --enable-maintainer-mode
> > - make all-bfd all-libiberty regenerate -j1
> > - for gdb: make all -C gdb/data-directory -j1
> > - make all -jXXX
> >
> > Making 'all' in bfd and libiberty is needed by some XXX-gen host
> > programs in opcodes.
> >
> > The advantage (for instance for CI) is that we can regenerate files at
> > -j1, thus avoiding the existing race conditions, and build the rest
> > with -j XXX.
> >
> > Among drawbacks:
> > - most sub-components use Makefile.am, but gdb does not: this may make
> >   maintenance more complex (different rules for different projects)
> > - maintaining such ad-hoc "regenerate" rules would require special
> >   attention from maintainers/reviewers
> > - dependency on -all-bfd and all-libiberty is probably not fully
> >    intuitive, but should not be a problem if the "regenerate" rules
> >    are used after a full build for instance
> >
> > Of course Makefile.def/Makefile.tpl would need further cleanup as I
> > didn't try to take gcc into account is this patch.
> >
> > Thoughts?
>
> My first thought it: why is it a Makefile target, instead of some script
> on the side (like autoregen.sh).  It would be nice / useful to be
> able to it without configuring / building anything.  For instance, the
> autoregen buildbot job could run it without configuring anything.
> Ideally, the buildbot wouldn't maintain its own autoregen.py file on the
> side, it would just use whatever is in the repo.

Firstly because of what you mention later: some regeneration steps
require building host tools first, like the XXX-gen in opcodes.

Since the existing Makefiles already contain the rules to autoregen
all these files, it seemed natural to me to reuse them, to avoid
reinventing the wheel with the risk of introducing new bugs.

This involves changes in places where I've never looked at before, so
I'd rather reuse as much existing support as possible.

For instance, there are the generators in opcodes/, but also things in
sim/, bfd/, updates to the docs and potfiles. In gcc, there's also
something "unusual" in fixincludes/ and libgfortran/

In fact, I considered also including 'configure', 'Makefile.in',
etc... in the 'regenerate' target, it does not seem natural to me to
invoke a script on the side, where you have to replicate the behaviour
of existing Makefiles, possibly getting out-of-sync when someone
forgets to update either Makefile or autoregen.py. What is currently
missing is a way to easily regenerate files without having to run a
full 'make all' (which currently takes care of calling autoconf &
friends to update configure/Makefile.in).

But yeah, having to configure before being able to regenerate files is
a bit awkward too :-)


>
> Looking at the rule to re-generate copying.c in gdb for instance:
>
>     # Make copying.c from COPYING
>     $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
>            awk -f $(srcdir)/copying.awk \
>                < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp
>            mv $(srcdir)/copying.tmp $(srcdir)/copying.c
>
> There is nothing in this code that requires having configured the source
> tree.  This code could for instance be moved to some
> generate-copying-c.sh script.  generate-copying-c.sh could be called by
> an hypothetical autoregen.sh script, as well as the copying.c Makefile
> target, if we want to continue supporting the maintainer mode.
Wouldn't it be more obscure than now? Currently such build rules are
all in the relevant Makefile. You'd have to open several scripts to
discover what's involved with updating copying.c

>
> Much like your regenerate targets, an autoregen.sh script in a given
> directory would be responsible to re-generate all the files in this
> directory that are generated and checked in git.  It would also be
> responsible to call any autoregen.sh file in subdirectories.
Makefiles already have all that in place :-)
Except if you consider that you'd want to ignore timestamps and always
regenerate things?


> There's just the issue of files that are generated using tools that are
> compiled.  When experimenting with maintainer mode the other day, I
> stumbled on the opcodes/i386-gen, for instance.  I don't have a good
> solution to that, except to rewrite these tools in a scripting language
> like Python.

So for opcodes, it currently means rewriting such programs for i386,
aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
generator.
Not sure how to find volunteers?

Christophe

>
> Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-15  8:50   ` Christophe Lyon
@ 2024-03-15 14:13     ` Eric Gallager
  2024-03-15 14:25       ` Tom Tromey
  2024-03-18 16:13       ` Christophe Lyon
  2024-03-16 17:16     ` Simon Marchi
       [not found]     ` <78f1d113-f8ac-4a76-8dea-9f92519c1a89@linux.ibm.com>
  2 siblings, 2 replies; 21+ messages in thread
From: Eric Gallager @ 2024-03-15 14:13 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: Simon Marchi, binutils, gdb, gcc

On Fri, Mar 15, 2024 at 4:53 AM Christophe Lyon via Gcc <gcc@gcc.gnu.org> wrote:
>
> On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
> >
> >
> >
> > On 2024-03-13 04:02, Christophe Lyon via Gdb wrote:
> > > Hi!
> > >
> > > After recent discussions on IRC and on the lists about maintainer-mode
> > > and various problems with auto-generated source files, I've written
> > > this small prototype.
> > >
> > > Based on those discussions, I assumed that people generally want to
> > > update autotools files using a script similar to autoregen.py, which
> > > takes care of running aclocal, autoheader, automake and autoconf as
> > > appropriate.
> > >
> > > What is currently missing is a "simple" way of regenerating other
> > > files, which happens normally with --enable-maintainer-mode (which is
> > > reportedly broken).  This patch as a "regenerate" Makefile target
> > > which can be called to update those files, provided
> > > --enable-maintainer-mode is used.
> > >
> > > I tried this approach with the following workflow for binutils/gdb:
> > > - run autoregen.py in srcdir
> > > - cd builddir
> > > - configure --enable-maintainer-mode
> > > - make all-bfd all-libiberty regenerate -j1
> > > - for gdb: make all -C gdb/data-directory -j1
> > > - make all -jXXX
> > >
> > > Making 'all' in bfd and libiberty is needed by some XXX-gen host
> > > programs in opcodes.
> > >
> > > The advantage (for instance for CI) is that we can regenerate files at
> > > -j1, thus avoiding the existing race conditions, and build the rest
> > > with -j XXX.
> > >
> > > Among drawbacks:
> > > - most sub-components use Makefile.am, but gdb does not: this may make
> > >   maintenance more complex (different rules for different projects)
> > > - maintaining such ad-hoc "regenerate" rules would require special
> > >   attention from maintainers/reviewers
> > > - dependency on -all-bfd and all-libiberty is probably not fully
> > >    intuitive, but should not be a problem if the "regenerate" rules
> > >    are used after a full build for instance
> > >
> > > Of course Makefile.def/Makefile.tpl would need further cleanup as I
> > > didn't try to take gcc into account is this patch.
> > >
> > > Thoughts?
> >
> > My first thought it: why is it a Makefile target, instead of some script
> > on the side (like autoregen.sh).  It would be nice / useful to be
> > able to it without configuring / building anything.  For instance, the
> > autoregen buildbot job could run it without configuring anything.
> > Ideally, the buildbot wouldn't maintain its own autoregen.py file on the
> > side, it would just use whatever is in the repo.
>
> Firstly because of what you mention later: some regeneration steps
> require building host tools first, like the XXX-gen in opcodes.
>
> Since the existing Makefiles already contain the rules to autoregen
> all these files, it seemed natural to me to reuse them, to avoid
> reinventing the wheel with the risk of introducing new bugs.
>
> This involves changes in places where I've never looked at before, so
> I'd rather reuse as much existing support as possible.
>
> For instance, there are the generators in opcodes/, but also things in
> sim/, bfd/, updates to the docs and potfiles. In gcc, there's also
> something "unusual" in fixincludes/ and libgfortran/
>
> In fact, I considered also including 'configure', 'Makefile.in',
> etc... in the 'regenerate' target, it does not seem natural to me to
> invoke a script on the side, where you have to replicate the behaviour
> of existing Makefiles, possibly getting out-of-sync when someone
> forgets to update either Makefile or autoregen.py. What is currently
> missing is a way to easily regenerate files without having to run a
> full 'make all' (which currently takes care of calling autoconf &
> friends to update configure/Makefile.in).
>
> But yeah, having to configure before being able to regenerate files is
> a bit awkward too :-)
>
>
> >
> > Looking at the rule to re-generate copying.c in gdb for instance:
> >
> >     # Make copying.c from COPYING
> >     $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
> >            awk -f $(srcdir)/copying.awk \
> >                < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp
> >            mv $(srcdir)/copying.tmp $(srcdir)/copying.c
> >
> > There is nothing in this code that requires having configured the source
> > tree.  This code could for instance be moved to some
> > generate-copying-c.sh script.  generate-copying-c.sh could be called by
> > an hypothetical autoregen.sh script, as well as the copying.c Makefile
> > target, if we want to continue supporting the maintainer mode.
> Wouldn't it be more obscure than now? Currently such build rules are
> all in the relevant Makefile. You'd have to open several scripts to
> discover what's involved with updating copying.c
>

Yeah I agree that it's good to keep all build rules in the Makefile;
if there's a possibility of something changing, things that depend
upon it need to know, and the best way to express those dependencies
is in the Makefile.

> >
> > Much like your regenerate targets, an autoregen.sh script in a given
> > directory would be responsible to re-generate all the files in this
> > directory that are generated and checked in git.  It would also be
> > responsible to call any autoregen.sh file in subdirectories.
> Makefiles already have all that in place :-)
> Except if you consider that you'd want to ignore timestamps and always
> regenerate things?
>
>
> > There's just the issue of files that are generated using tools that are
> > compiled.  When experimenting with maintainer mode the other day, I
> > stumbled on the opcodes/i386-gen, for instance.  I don't have a good
> > solution to that, except to rewrite these tools in a scripting language
> > like Python.
>
> So for opcodes, it currently means rewriting such programs for i386,
> aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
> generator.

Also there are the files generated by cgen, too, which no one seems to
know how to regenerate, either. And then in bfd there's that chew
program in the doc subdir. And then in the binutils subdirectory
proper there's that sysinfo tool for generating sysroff.[ch].

> Not sure how to find volunteers?
>
> Christophe
>
> >
> > Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-15 14:13     ` Eric Gallager
@ 2024-03-15 14:25       ` Tom Tromey
  2024-03-16 17:30         ` Simon Marchi
  2024-03-18 17:28         ` Christophe Lyon
  2024-03-18 16:13       ` Christophe Lyon
  1 sibling, 2 replies; 21+ messages in thread
From: Tom Tromey @ 2024-03-15 14:25 UTC (permalink / raw)
  To: Eric Gallager; +Cc: Christophe Lyon, Simon Marchi, binutils, gdb, gcc

>>>>> "Eric" == Eric Gallager <egall@gwmail.gwu.edu> writes:

Eric> Also there are the files generated by cgen, too, which no one seems to
Eric> know how to regenerate, either.

I thought I sent out some info on this a while ago.

Anyway what I do is make a symlink to the cgen source tree in the
binutils-gdb source tree, then configure with --enable-cgen-maint.
Then I make sure to build with 'make GUILE=guile3.0'.

It could be better but that would require someone to actually work on
cgen.

Eric> And then in bfd there's that chew
Eric> program in the doc subdir. And then in the binutils subdirectory
Eric> proper there's that sysinfo tool for generating sysroff.[ch].

gdb used to use a mish-mash of different approaches, some quite strange,
but over the last few years we standardized on Python scripts that
generate files.  They're written to be seamless -- just invoke in the
source dir; the output is then just part of your patch.  No special
configure options are needed.  On the whole this has been a big
improvement.

Tom

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-15  8:50   ` Christophe Lyon
  2024-03-15 14:13     ` Eric Gallager
@ 2024-03-16 17:16     ` Simon Marchi
  2024-03-18 17:25       ` Christophe Lyon
       [not found]     ` <78f1d113-f8ac-4a76-8dea-9f92519c1a89@linux.ibm.com>
  2 siblings, 1 reply; 21+ messages in thread
From: Simon Marchi @ 2024-03-16 17:16 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: binutils, gdb, gcc



On 2024-03-15 04:50, Christophe Lyon via Gdb wrote:
> On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
>> My first thought it: why is it a Makefile target, instead of some script
>> on the side (like autoregen.sh).  It would be nice / useful to be
>> able to it without configuring / building anything.  For instance, the
>> autoregen buildbot job could run it without configuring anything.
>> Ideally, the buildbot wouldn't maintain its own autoregen.py file on the
>> side, it would just use whatever is in the repo.
> 
> Firstly because of what you mention later: some regeneration steps
> require building host tools first, like the XXX-gen in opcodes.

"build" and not "host", I think?

> Since the existing Makefiles already contain the rules to autoregen
> all these files, it seemed natural to me to reuse them, to avoid
> reinventing the wheel with the risk of introducing new bugs.

I understand.  Although one advantage of moving the actual code out of
the Makefile (even if there's still a Makefile rule calling the external
script), is that it's much easier to maintain.  Editors are much more
useful when editing a standalone shell script than editing shell code in
a Makefile target.  It doesn't have to be this big one liner if you want
to use variables, you don't need to escape $, you can run it through
linters, you can call it by hand, etc.  This is what I did here, for
instance:

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f39632d9579d3c97f1e50a728efed3c5409747d2

So I think there's value in any case of moving the regeneration logic
out of the Makefiles per se.

> This involves changes in places where I've never looked at before, so
> I'd rather reuse as much existing support as possible.
> 
> For instance, there are the generators in opcodes/, but also things in
> sim/, bfd/, updates to the docs and potfiles. In gcc, there's also
> something "unusual" in fixincludes/ and libgfortran/
> 
> In fact, I considered also including 'configure', 'Makefile.in',
> etc... in the 'regenerate' target, it does not seem natural to me to
> invoke a script on the side, where you have to replicate the behaviour
> of existing Makefiles, possibly getting out-of-sync when someone
> forgets to update either Makefile or autoregen.py.

I'm not sure I follow.  Are you referring to the rules that automake
automatically puts to re-generate Makefile.in and others when
Makefile.am has changed?  Your regenerate target would depend on those
builtin rules?

Let's say my generate-autostuff.sh script does:

  aclocal --some-flags
  automake --some-other-flags
  autoconf --some-other-other-flags

And the checked-in Makefile.in is regenerated based on that.  Wouldn't
the built-in rules just call aclocal/automake/autoconf with those same
flags?  I don't see why they would get out of sync.

> What is currently
> missing is a way to easily regenerate files without having to run a
> full 'make all' (which currently takes care of calling autoconf &
> friends to update configure/Makefile.in).
> 
> But yeah, having to configure before being able to regenerate files is
> a bit awkward too :-)

I understand the constraints your are working with, and I guess that
doing:

  ./configure && make regenerate

is not too bad.  The buildbot could probably do that... except that
it would need a way to force regenerate everything, ignoring the
timestamps.  Perhaps this option of GNU make would work?

       -B, --always-make
            Unconditionally make all targets.

>> Looking at the rule to re-generate copying.c in gdb for instance:
>>
>>     # Make copying.c from COPYING
>>     $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
>>            awk -f $(srcdir)/copying.awk \
>>                < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp
>>            mv $(srcdir)/copying.tmp $(srcdir)/copying.c
>>
>> There is nothing in this code that requires having configured the source
>> tree.  This code could for instance be moved to some
>> generate-copying-c.sh script.  generate-copying-c.sh could be called by
>> an hypothetical autoregen.sh script, as well as the copying.c Makefile
>> target, if we want to continue supporting the maintainer mode.
> Wouldn't it be more obscure than now? Currently such build rules are
> all in the relevant Makefile. You'd have to open several scripts to
> discover what's involved with updating copying.c

Maybe, that's subjective :).  The logic to regenerate would be in one
script, and yes that script could be invoked from different places.  At
least the paper trail would be relatively easy to follow.

>> Much like your regenerate targets, an autoregen.sh script in a given
>> directory would be responsible to re-generate all the files in this
>> directory that are generated and checked in git.  It would also be
>> responsible to call any autoregen.sh file in subdirectories.
> Makefiles already have all that in place :-)
> Except if you consider that you'd want to ignore timestamps and always
> regenerate things?

Yeah, for the buildbot autoregen job, since its job it to verify that
everything has been generated correctly, we would like to regenerate
everything, regardless of the timestamps.

Speaking of "already have all that in place", maintaining a script in
the buildbot to re-implement all the re-generation logic is the worst of
all, so I would love to avoid having to reimplemement some of that logic
out of the repo :).

>> compiled.  When experimenting with maintainer mode the other day, I
>> stumbled on the opcodes/i386-gen, for instance.  I don't have a good
>> solution to that, except to rewrite these tools in a scripting language
>> like Python.
> 
> So for opcodes, it currently means rewriting such programs for i386,
> aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
> generator.
> Not sure how to find volunteers?

I would love to do that if I had infinite time :).  Of course, the
current state of things + finite amount of resources are some contraints
you are working with, and I completely undertand that.

Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-15 14:25       ` Tom Tromey
@ 2024-03-16 17:30         ` Simon Marchi
  2024-03-18 17:28         ` Christophe Lyon
  1 sibling, 0 replies; 21+ messages in thread
From: Simon Marchi @ 2024-03-16 17:30 UTC (permalink / raw)
  To: Tom Tromey, Eric Gallager; +Cc: Christophe Lyon, binutils, gdb, gcc



On 2024-03-15 10:25, Tom Tromey wrote:
> gdb used to use a mish-mash of different approaches, some quite strange,
> but over the last few years we standardized on Python scripts that
> generate files.  They're written to be seamless -- just invoke in the
> source dir; the output is then just part of your patch.  No special
> configure options are needed.  On the whole this has been a big
> improvement.

The two that come in mind for gdb are (there are more but I don't know
them):

 - gdb/gdbarch.py
 - gdb/make-target-delegates.py

gdbarch.py used to be a shell script, but moving it to Python made it
much faster, easier to maintain (as in change how gdbarch hooks are
generated) and easier to update (as in modifying the gdbarch hook list).

Now, a wishlist I have for generated files (I might do that one day):

 - Make all generated files (regardless of if they are checked in the
   repo or not) end with the -gen suffix (like gdbarch-gen.h), so it's
   easier to know that a file is generated.
 - make all generator tools have the same name pattern (e.g.
   make-gdbarch.py, make-target-delegates.py, make-init-c.sh, etc).

Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-15 14:13     ` Eric Gallager
  2024-03-15 14:25       ` Tom Tromey
@ 2024-03-18 16:13       ` Christophe Lyon
  1 sibling, 0 replies; 21+ messages in thread
From: Christophe Lyon @ 2024-03-18 16:13 UTC (permalink / raw)
  To: Eric Gallager; +Cc: Simon Marchi, binutils, gdb, gcc

On Fri, 15 Mar 2024 at 15:13, Eric Gallager <egall@gwmail.gwu.edu> wrote:
>
> On Fri, Mar 15, 2024 at 4:53 AM Christophe Lyon via Gcc <gcc@gcc.gnu.org> wrote:
> >
> > On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
> > >
> > >
> > >
> > > On 2024-03-13 04:02, Christophe Lyon via Gdb wrote:
> > > > Hi!
> > > >
> > > > After recent discussions on IRC and on the lists about maintainer-mode
> > > > and various problems with auto-generated source files, I've written
> > > > this small prototype.
> > > >
> > > > Based on those discussions, I assumed that people generally want to
> > > > update autotools files using a script similar to autoregen.py, which
> > > > takes care of running aclocal, autoheader, automake and autoconf as
> > > > appropriate.
> > > >
> > > > What is currently missing is a "simple" way of regenerating other
> > > > files, which happens normally with --enable-maintainer-mode (which is
> > > > reportedly broken).  This patch as a "regenerate" Makefile target
> > > > which can be called to update those files, provided
> > > > --enable-maintainer-mode is used.
> > > >
> > > > I tried this approach with the following workflow for binutils/gdb:
> > > > - run autoregen.py in srcdir
> > > > - cd builddir
> > > > - configure --enable-maintainer-mode
> > > > - make all-bfd all-libiberty regenerate -j1
> > > > - for gdb: make all -C gdb/data-directory -j1
> > > > - make all -jXXX
> > > >
> > > > Making 'all' in bfd and libiberty is needed by some XXX-gen host
> > > > programs in opcodes.
> > > >
> > > > The advantage (for instance for CI) is that we can regenerate files at
> > > > -j1, thus avoiding the existing race conditions, and build the rest
> > > > with -j XXX.
> > > >
> > > > Among drawbacks:
> > > > - most sub-components use Makefile.am, but gdb does not: this may make
> > > >   maintenance more complex (different rules for different projects)
> > > > - maintaining such ad-hoc "regenerate" rules would require special
> > > >   attention from maintainers/reviewers
> > > > - dependency on -all-bfd and all-libiberty is probably not fully
> > > >    intuitive, but should not be a problem if the "regenerate" rules
> > > >    are used after a full build for instance
> > > >
> > > > Of course Makefile.def/Makefile.tpl would need further cleanup as I
> > > > didn't try to take gcc into account is this patch.
> > > >
> > > > Thoughts?
> > >
> > > My first thought it: why is it a Makefile target, instead of some script
> > > on the side (like autoregen.sh).  It would be nice / useful to be
> > > able to it without configuring / building anything.  For instance, the
> > > autoregen buildbot job could run it without configuring anything.
> > > Ideally, the buildbot wouldn't maintain its own autoregen.py file on the
> > > side, it would just use whatever is in the repo.
> >
> > Firstly because of what you mention later: some regeneration steps
> > require building host tools first, like the XXX-gen in opcodes.
> >
> > Since the existing Makefiles already contain the rules to autoregen
> > all these files, it seemed natural to me to reuse them, to avoid
> > reinventing the wheel with the risk of introducing new bugs.
> >
> > This involves changes in places where I've never looked at before, so
> > I'd rather reuse as much existing support as possible.
> >
> > For instance, there are the generators in opcodes/, but also things in
> > sim/, bfd/, updates to the docs and potfiles. In gcc, there's also
> > something "unusual" in fixincludes/ and libgfortran/
> >
> > In fact, I considered also including 'configure', 'Makefile.in',
> > etc... in the 'regenerate' target, it does not seem natural to me to
> > invoke a script on the side, where you have to replicate the behaviour
> > of existing Makefiles, possibly getting out-of-sync when someone
> > forgets to update either Makefile or autoregen.py. What is currently
> > missing is a way to easily regenerate files without having to run a
> > full 'make all' (which currently takes care of calling autoconf &
> > friends to update configure/Makefile.in).
> >
> > But yeah, having to configure before being able to regenerate files is
> > a bit awkward too :-)
> >
> >
> > >
> > > Looking at the rule to re-generate copying.c in gdb for instance:
> > >
> > >     # Make copying.c from COPYING
> > >     $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
> > >            awk -f $(srcdir)/copying.awk \
> > >                < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp
> > >            mv $(srcdir)/copying.tmp $(srcdir)/copying.c
> > >
> > > There is nothing in this code that requires having configured the source
> > > tree.  This code could for instance be moved to some
> > > generate-copying-c.sh script.  generate-copying-c.sh could be called by
> > > an hypothetical autoregen.sh script, as well as the copying.c Makefile
> > > target, if we want to continue supporting the maintainer mode.
> > Wouldn't it be more obscure than now? Currently such build rules are
> > all in the relevant Makefile. You'd have to open several scripts to
> > discover what's involved with updating copying.c
> >
>
> Yeah I agree that it's good to keep all build rules in the Makefile;
> if there's a possibility of something changing, things that depend
> upon it need to know, and the best way to express those dependencies
> is in the Makefile.
>
> > >
> > > Much like your regenerate targets, an autoregen.sh script in a given
> > > directory would be responsible to re-generate all the files in this
> > > directory that are generated and checked in git.  It would also be
> > > responsible to call any autoregen.sh file in subdirectories.
> > Makefiles already have all that in place :-)
> > Except if you consider that you'd want to ignore timestamps and always
> > regenerate things?
> >
> >
> > > There's just the issue of files that are generated using tools that are
> > > compiled.  When experimenting with maintainer mode the other day, I
> > > stumbled on the opcodes/i386-gen, for instance.  I don't have a good
> > > solution to that, except to rewrite these tools in a scripting language
> > > like Python.
> >
> > So for opcodes, it currently means rewriting such programs for i386,
> > aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
> > generator.
>
> Also there are the files generated by cgen, too, which no one seems to

I had heard about cgen ages ago but I had forgotten about them.
And your message made me discover configure's option --enable-cgen-maint :-)

> know how to regenerate, either. And then in bfd there's that chew
> program in the doc subdir. And then in the binutils subdirectory
> proper there's that sysinfo tool for generating sysroff.[ch].
>
> > Not sure how to find volunteers?
> >
> > Christophe
> >
> > >
> > > Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-16 17:16     ` Simon Marchi
@ 2024-03-18 17:25       ` Christophe Lyon
  2024-03-19 17:11         ` Christophe Lyon
  2024-03-20 15:34         ` Simon Marchi
  0 siblings, 2 replies; 21+ messages in thread
From: Christophe Lyon @ 2024-03-18 17:25 UTC (permalink / raw)
  To: Simon Marchi; +Cc: binutils, gdb, gcc

On Sat, 16 Mar 2024 at 18:16, Simon Marchi <simark@simark.ca> wrote:
>
>
>
> On 2024-03-15 04:50, Christophe Lyon via Gdb wrote:
> > On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
> >> My first thought it: why is it a Makefile target, instead of some script
> >> on the side (like autoregen.sh).  It would be nice / useful to be
> >> able to it without configuring / building anything.  For instance, the
> >> autoregen buildbot job could run it without configuring anything.
> >> Ideally, the buildbot wouldn't maintain its own autoregen.py file on the
> >> side, it would just use whatever is in the repo.
> >
> > Firstly because of what you mention later: some regeneration steps
> > require building host tools first, like the XXX-gen in opcodes.
>
> "build" and not "host", I think?

yes, sorry

> > Since the existing Makefiles already contain the rules to autoregen
> > all these files, it seemed natural to me to reuse them, to avoid
> > reinventing the wheel with the risk of introducing new bugs.
>
> I understand.  Although one advantage of moving the actual code out of
> the Makefile (even if there's still a Makefile rule calling the external
> script), is that it's much easier to maintain.  Editors are much more
> useful when editing a standalone shell script than editing shell code in
> a Makefile target.  It doesn't have to be this big one liner if you want
> to use variables, you don't need to escape $, you can run it through
> linters, you can call it by hand, etc.  This is what I did here, for
> instance:
>
> https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f39632d9579d3c97f1e50a728efed3c5409747d2
>
> So I think there's value in any case of moving the regeneration logic
> out of the Makefiles per se.
>
In this case, the generation rules look simple enough indeed.
But as mentioned elsewhere in the thread, there are more complex
cases, which involve building helper tools, which have dependencies on
bfd and libiberty for instance. I'm not sure that's easily/naturally
scriptable?
There's also 'chew' in bfd/

> > This involves changes in places where I've never looked at before, so
> > I'd rather reuse as much existing support as possible.
> >
> > For instance, there are the generators in opcodes/, but also things in
> > sim/, bfd/, updates to the docs and potfiles. In gcc, there's also
> > something "unusual" in fixincludes/ and libgfortran/
> >
> > In fact, I considered also including 'configure', 'Makefile.in',
> > etc... in the 'regenerate' target, it does not seem natural to me to
> > invoke a script on the side, where you have to replicate the behaviour
> > of existing Makefiles, possibly getting out-of-sync when someone
> > forgets to update either Makefile or autoregen.py.
>
> I'm not sure I follow.  Are you referring to the rules that automake
> automatically puts to re-generate Makefile.in and others when
> Makefile.am has changed?  Your regenerate target would depend on those
> builtin rules?
Yes, "regenerate" would include "configure, Makeifile.in, configh"
(as/if needed) in its list of dependencies.

>
> Let's say my generate-autostuff.sh script does:
>
>   aclocal --some-flags
>   automake --some-other-flags
>   autoconf --some-other-other-flags
>
> And the checked-in Makefile.in is regenerated based on that.  Wouldn't
> the built-in rules just call aclocal/automake/autoconf with those same
> flags?  I don't see why they would get out of sync.
Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit
more complex
than just calling automake. IIUC it calls automake --foreign it any of
*.m4 file from $(am__configure_deps) that is newer than Makefile.in
(with an early exit in the loop), does nothing if Makefile.am or
doc/local.mk are newer than Makefile.in, and then calls 'automake
--foreign Makefile'

I've never looked closely at that rule (I suppose he does what it's
intended to do ;-) ), but why not call automake once in $srcdir then
once in $top_srcdir?
TBH I'd rather not spend ages figuring out all this magic :-)

But yeah, maybe some careful looking at these rules might lead to a
couple of simple shell lines.


>
> > What is currently
> > missing is a way to easily regenerate files without having to run a
> > full 'make all' (which currently takes care of calling autoconf &
> > friends to update configure/Makefile.in).
> >
> > But yeah, having to configure before being able to regenerate files is
> > a bit awkward too :-)
>
> I understand the constraints your are working with, and I guess that
> doing:
>
>   ./configure && make regenerate
>
> is not too bad.  The buildbot could probably do that... except that
> it would need a way to force regenerate everything, ignoring the
> timestamps.  Perhaps this option of GNU make would work?
>
>        -B, --always-make
>             Unconditionally make all targets.
I noticed that option when writing my previous message, maybe that would work.

> >> Looking at the rule to re-generate copying.c in gdb for instance:
> >>
> >>     # Make copying.c from COPYING
> >>     $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
> >>            awk -f $(srcdir)/copying.awk \
> >>                < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp
> >>            mv $(srcdir)/copying.tmp $(srcdir)/copying.c
> >>
> >> There is nothing in this code that requires having configured the source
> >> tree.  This code could for instance be moved to some
> >> generate-copying-c.sh script.  generate-copying-c.sh could be called by
> >> an hypothetical autoregen.sh script, as well as the copying.c Makefile
> >> target, if we want to continue supporting the maintainer mode.
> > Wouldn't it be more obscure than now? Currently such build rules are
> > all in the relevant Makefile. You'd have to open several scripts to
> > discover what's involved with updating copying.c
>
> Maybe, that's subjective :).  The logic to regenerate would be in one
> script, and yes that script could be invoked from different places.  At
> least the paper trail would be relatively easy to follow.
>
> >> Much like your regenerate targets, an autoregen.sh script in a given
> >> directory would be responsible to re-generate all the files in this
> >> directory that are generated and checked in git.  It would also be
> >> responsible to call any autoregen.sh file in subdirectories.
> > Makefiles already have all that in place :-)
> > Except if you consider that you'd want to ignore timestamps and always
> > regenerate things?
>
> Yeah, for the buildbot autoregen job, since its job it to verify that
> everything has been generated correctly, we would like to regenerate
> everything, regardless of the timestamps.
The bot I want to put in place would regenerate things as they are
supposed to be, then build and run the testsuite to make sure that
what is supposed to be committed would work (if the committer
regenerates everything correctly)



> Speaking of "already have all that in place", maintaining a script in
> the buildbot to re-implement all the re-generation logic is the worst of
> all, so I would love to avoid having to reimplemement some of that logic
> out of the repo :).
agreed!
autoregen.py should probably be moved from the bot to the binutils-gdb
and gcc repos (but we'd have to remember to keep them in sync, like
many other files already...)

> >> compiled.  When experimenting with maintainer mode the other day, I
> >> stumbled on the opcodes/i386-gen, for instance.  I don't have a good
> >> solution to that, except to rewrite these tools in a scripting language
> >> like Python.
> >
> > So for opcodes, it currently means rewriting such programs for i386,
> > aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
> > generator.
> > Not sure how to find volunteers?
>
> I would love to do that if I had infinite time :).  Of course, the
> current state of things + finite amount of resources are some contraints
> you are working with, and I completely undertand that.

:-)

Thanks,

Christophe

>
> Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-15 14:25       ` Tom Tromey
  2024-03-16 17:30         ` Simon Marchi
@ 2024-03-18 17:28         ` Christophe Lyon
  2024-03-20 15:11           ` Simon Marchi
  1 sibling, 1 reply; 21+ messages in thread
From: Christophe Lyon @ 2024-03-18 17:28 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Eric Gallager, Simon Marchi, binutils, gdb, gcc

On Fri, 15 Mar 2024 at 15:25, Tom Tromey <tom@tromey.com> wrote:
>
> >>>>> "Eric" == Eric Gallager <egall@gwmail.gwu.edu> writes:
>
> Eric> Also there are the files generated by cgen, too, which no one seems to
> Eric> know how to regenerate, either.
>
> I thought I sent out some info on this a while ago.
>
> Anyway what I do is make a symlink to the cgen source tree in the
> binutils-gdb source tree, then configure with --enable-cgen-maint.
> Then I make sure to build with 'make GUILE=guile3.0'.
>
> It could be better but that would require someone to actually work on
> cgen.
>
> Eric> And then in bfd there's that chew
> Eric> program in the doc subdir. And then in the binutils subdirectory
> Eric> proper there's that sysinfo tool for generating sysroff.[ch].
>
> gdb used to use a mish-mash of different approaches, some quite strange,
> but over the last few years we standardized on Python scripts that
> generate files.  They're written to be seamless -- just invoke in the
> source dir; the output is then just part of your patch.  No special
> configure options are needed.  On the whole this has been a big
> improvement.
>
Good to know that this is perceived as a big improvement, that's a
strong argument for moving to a script.

I'm not up-to-date with gdb's policy about patches: are they supposed
to be posted with or without the regenerated parts included?
IIUC they are not included in patch submissions for binutils and gcc,
which makes the pre-commit CI miss some patches.

Thanks,

Christophe

> Tom

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-18 17:25       ` Christophe Lyon
@ 2024-03-19 17:11         ` Christophe Lyon
  2024-03-19 18:03           ` Tom Tromey
  2024-03-20 15:34         ` Simon Marchi
  1 sibling, 1 reply; 21+ messages in thread
From: Christophe Lyon @ 2024-03-19 17:11 UTC (permalink / raw)
  To: Simon Marchi; +Cc: binutils, gdb, gcc

Hi,

On Mon, 18 Mar 2024 at 18:25, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
>
> On Sat, 16 Mar 2024 at 18:16, Simon Marchi <simark@simark.ca> wrote:
> >
> >
> >
> > On 2024-03-15 04:50, Christophe Lyon via Gdb wrote:
> > > On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
> > >> My first thought it: why is it a Makefile target, instead of some script
> > >> on the side (like autoregen.sh).  It would be nice / useful to be
> > >> able to it without configuring / building anything.  For instance, the
> > >> autoregen buildbot job could run it without configuring anything.
> > >> Ideally, the buildbot wouldn't maintain its own autoregen.py file on the
> > >> side, it would just use whatever is in the repo.
> > >
> > > Firstly because of what you mention later: some regeneration steps
> > > require building host tools first, like the XXX-gen in opcodes.
> >
> > "build" and not "host", I think?
>
> yes, sorry
>
> > > Since the existing Makefiles already contain the rules to autoregen
> > > all these files, it seemed natural to me to reuse them, to avoid
> > > reinventing the wheel with the risk of introducing new bugs.
> >
> > I understand.  Although one advantage of moving the actual code out of
> > the Makefile (even if there's still a Makefile rule calling the external
> > script), is that it's much easier to maintain.  Editors are much more
> > useful when editing a standalone shell script than editing shell code in
> > a Makefile target.  It doesn't have to be this big one liner if you want
> > to use variables, you don't need to escape $, you can run it through
> > linters, you can call it by hand, etc.  This is what I did here, for
> > instance:
> >
> > https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f39632d9579d3c97f1e50a728efed3c5409747d2
> >
> > So I think there's value in any case of moving the regeneration logic
> > out of the Makefiles per se.
> >
> In this case, the generation rules look simple enough indeed.
> But as mentioned elsewhere in the thread, there are more complex
> cases, which involve building helper tools, which have dependencies on
> bfd and libiberty for instance. I'm not sure that's easily/naturally
> scriptable?
> There's also 'chew' in bfd/
>
> > > This involves changes in places where I've never looked at before, so
> > > I'd rather reuse as much existing support as possible.
> > >
> > > For instance, there are the generators in opcodes/, but also things in
> > > sim/, bfd/, updates to the docs and potfiles. In gcc, there's also
> > > something "unusual" in fixincludes/ and libgfortran/
> > >
> > > In fact, I considered also including 'configure', 'Makefile.in',
> > > etc... in the 'regenerate' target, it does not seem natural to me to
> > > invoke a script on the side, where you have to replicate the behaviour
> > > of existing Makefiles, possibly getting out-of-sync when someone
> > > forgets to update either Makefile or autoregen.py.
> >
> > I'm not sure I follow.  Are you referring to the rules that automake
> > automatically puts to re-generate Makefile.in and others when
> > Makefile.am has changed?  Your regenerate target would depend on those
> > builtin rules?
> Yes, "regenerate" would include "configure, Makeifile.in, configh"
> (as/if needed) in its list of dependencies.
>
> >
> > Let's say my generate-autostuff.sh script does:
> >
> >   aclocal --some-flags
> >   automake --some-other-flags
> >   autoconf --some-other-other-flags
> >
> > And the checked-in Makefile.in is regenerated based on that.  Wouldn't
> > the built-in rules just call aclocal/automake/autoconf with those same
> > flags?  I don't see why they would get out of sync.
> Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit
> more complex
> than just calling automake. IIUC it calls automake --foreign it any of
> *.m4 file from $(am__configure_deps) that is newer than Makefile.in
> (with an early exit in the loop), does nothing if Makefile.am or
> doc/local.mk are newer than Makefile.in, and then calls 'automake
> --foreign Makefile'
>
> I've never looked closely at that rule (I suppose he does what it's
> intended to do ;-) ), but why not call automake once in $srcdir then
> once in $top_srcdir?
> TBH I'd rather not spend ages figuring out all this magic :-)
>
> But yeah, maybe some careful looking at these rules might lead to a
> couple of simple shell lines.
>

I looked a bit more closely at gcc, and noticed that ACLOCAL_AMFLAGS
is given different values at various parts of the source tree:
-I $(top_srcdir) -I $(top_srcdir)/config
-I ../config
-I ../config -I ..
-I ./config -I ../config
-I .. -I ../../config
-I .. -I ../config
-I ../.. -I ../../config
-I . -I .. -I ../config
-I m4

not sure if the current autoregen.py is in sync with that?

Also... I discovered the existence of an automake rule:
am--refresh which IIUC is intended to automake the update of Makefile
and its dependencies.

I'm by no means an autotool expert :-)

Christophe

>
> >
> > > What is currently
> > > missing is a way to easily regenerate files without having to run a
> > > full 'make all' (which currently takes care of calling autoconf &
> > > friends to update configure/Makefile.in).
> > >
> > > But yeah, having to configure before being able to regenerate files is
> > > a bit awkward too :-)
> >
> > I understand the constraints your are working with, and I guess that
> > doing:
> >
> >   ./configure && make regenerate
> >
> > is not too bad.  The buildbot could probably do that... except that
> > it would need a way to force regenerate everything, ignoring the
> > timestamps.  Perhaps this option of GNU make would work?
> >
> >        -B, --always-make
> >             Unconditionally make all targets.
> I noticed that option when writing my previous message, maybe that would work.
>
> > >> Looking at the rule to re-generate copying.c in gdb for instance:
> > >>
> > >>     # Make copying.c from COPYING
> > >>     $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk
> > >>            awk -f $(srcdir)/copying.awk \
> > >>                < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp
> > >>            mv $(srcdir)/copying.tmp $(srcdir)/copying.c
> > >>
> > >> There is nothing in this code that requires having configured the source
> > >> tree.  This code could for instance be moved to some
> > >> generate-copying-c.sh script.  generate-copying-c.sh could be called by
> > >> an hypothetical autoregen.sh script, as well as the copying.c Makefile
> > >> target, if we want to continue supporting the maintainer mode.
> > > Wouldn't it be more obscure than now? Currently such build rules are
> > > all in the relevant Makefile. You'd have to open several scripts to
> > > discover what's involved with updating copying.c
> >
> > Maybe, that's subjective :).  The logic to regenerate would be in one
> > script, and yes that script could be invoked from different places.  At
> > least the paper trail would be relatively easy to follow.
> >
> > >> Much like your regenerate targets, an autoregen.sh script in a given
> > >> directory would be responsible to re-generate all the files in this
> > >> directory that are generated and checked in git.  It would also be
> > >> responsible to call any autoregen.sh file in subdirectories.
> > > Makefiles already have all that in place :-)
> > > Except if you consider that you'd want to ignore timestamps and always
> > > regenerate things?
> >
> > Yeah, for the buildbot autoregen job, since its job it to verify that
> > everything has been generated correctly, we would like to regenerate
> > everything, regardless of the timestamps.
> The bot I want to put in place would regenerate things as they are
> supposed to be, then build and run the testsuite to make sure that
> what is supposed to be committed would work (if the committer
> regenerates everything correctly)
>
>
>
> > Speaking of "already have all that in place", maintaining a script in
> > the buildbot to re-implement all the re-generation logic is the worst of
> > all, so I would love to avoid having to reimplemement some of that logic
> > out of the repo :).
> agreed!
> autoregen.py should probably be moved from the bot to the binutils-gdb
> and gcc repos (but we'd have to remember to keep them in sync, like
> many other files already...)
>
> > >> compiled.  When experimenting with maintainer mode the other day, I
> > >> stumbled on the opcodes/i386-gen, for instance.  I don't have a good
> > >> solution to that, except to rewrite these tools in a scripting language
> > >> like Python.
> > >
> > > So for opcodes, it currently means rewriting such programs for i386,
> > > aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
> > > generator.
> > > Not sure how to find volunteers?
> >
> > I would love to do that if I had infinite time :).  Of course, the
> > current state of things + finite amount of resources are some contraints
> > you are working with, and I completely undertand that.
>
> :-)
>
> Thanks,
>
> Christophe
>
> >
> > Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-19 17:11         ` Christophe Lyon
@ 2024-03-19 18:03           ` Tom Tromey
  2024-03-20 12:05             ` Eric Gallager
  0 siblings, 1 reply; 21+ messages in thread
From: Tom Tromey @ 2024-03-19 18:03 UTC (permalink / raw)
  To: Christophe Lyon via Gdb; +Cc: Simon Marchi, Christophe Lyon, binutils, gcc

> not sure if the current autoregen.py is in sync with that?

I'm curious why "autoreconf -f" is insufficient.
It seems to me that this should work.

> Also... I discovered the existence of an automake rule:
> am--refresh which IIUC is intended to automake the update of Makefile
> and its dependencies.

Don't use that rule directly.  It's an implementation detail and
shouldn't be relied on.

thanks,
Tom

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-19 18:03           ` Tom Tromey
@ 2024-03-20 12:05             ` Eric Gallager
  0 siblings, 0 replies; 21+ messages in thread
From: Eric Gallager @ 2024-03-20 12:05 UTC (permalink / raw)
  To: Tom Tromey
  Cc: Christophe Lyon via Gdb, Simon Marchi, Christophe Lyon, binutils, gcc

On Tue, Mar 19, 2024 at 2:10 PM Tom Tromey <tom@tromey.com> wrote:
>
> > not sure if the current autoregen.py is in sync with that?
>
> I'm curious why "autoreconf -f" is insufficient.
> It seems to me that this should work.

`autoreconf -f` works fine in individual subdirectories, the problem
is that the top-level configure.ac doesn't use the AC_CONFIG_SUBDIRS
macro to specify its subdirectories, but rather uses its own
hand-rolled method of specifying subdirectories that autoreconf
doesn't know about. This means that autoreconf won't automatically
recurse into all the necessary subdirectories by itself automatically,
and instead has to be run manually in each subdirectory separately.
Also the various subdirectories are inconsistent about whether they
have a rule for running it (autoreconf) from the Makefile or not,
which usually comes down to whether the subdirectory uses automake for
its Makefile or not (the top-level Makefile doesn't; it uses its own
weird autogen-based regeneration method instead, which means that it
misses out on all the built-in rules that automake would implicitly
generate, including ones related to build system regeneration).

>
> > Also... I discovered the existence of an automake rule:
> > am--refresh which IIUC is intended to automake the update of Makefile
> > and its dependencies.
>
> Don't use that rule directly.  It's an implementation detail and
> shouldn't be relied on.
>
> thanks,
> Tom

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-18 17:28         ` Christophe Lyon
@ 2024-03-20 15:11           ` Simon Marchi
  0 siblings, 0 replies; 21+ messages in thread
From: Simon Marchi @ 2024-03-20 15:11 UTC (permalink / raw)
  To: Christophe Lyon, Tom Tromey; +Cc: Eric Gallager, binutils, gdb, gcc

On 3/18/24 13:28, Christophe Lyon via Gdb wrote:
> I'm not up-to-date with gdb's policy about patches: are they supposed
> to be posted with or without the regenerated parts included?
> IIUC they are not included in patch submissions for binutils and gcc,
> which makes the pre-commit CI miss some patches.

We post the patches with the regenerated parts.

Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-18 17:25       ` Christophe Lyon
  2024-03-19 17:11         ` Christophe Lyon
@ 2024-03-20 15:34         ` Simon Marchi
  2024-03-21 14:32           ` Christophe Lyon
  1 sibling, 1 reply; 21+ messages in thread
From: Simon Marchi @ 2024-03-20 15:34 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: binutils, gdb, gcc

On 3/18/24 13:25, Christophe Lyon wrote:
> Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit
> more complex
> than just calling automake. IIUC it calls automake --foreign it any of
> *.m4 file from $(am__configure_deps) that is newer than Makefile.in
> (with an early exit in the loop), does nothing if Makefile.am or
> doc/local.mk are newer than Makefile.in, and then calls 'automake
> --foreign Makefile'

The rules looks complex because they've been generated by automake, this
Makefile.in is not written by hand.  And I guess automake has put
`--foreign` there because foreign is used in Makefile.am:

  AUTOMAKE_OPTIONS = foreign no-dist

But a simple call so `automake -f` (or `autoreconf -f`) just works, as
automake picks up the foreign option from AUTOMAKE_OPTIONS, so a human
or an external script who wants to regenerate things would probably just
use that.

> The bot I want to put in place would regenerate things as they are
> supposed to be, then build and run the testsuite to make sure that
> what is supposed to be committed would work (if the committer
> regenerates everything correctly)

For your job, would it be fine to just force-regenerate everything and
ignore timestamps (just like the buildbot's autoregen job wants to do)?
It would waste a few cycles, but it would be much simpler.

Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-20 15:34         ` Simon Marchi
@ 2024-03-21 14:32           ` Christophe Lyon
  2024-03-25 14:19             ` Christophe Lyon
  0 siblings, 1 reply; 21+ messages in thread
From: Christophe Lyon @ 2024-03-21 14:32 UTC (permalink / raw)
  To: Simon Marchi; +Cc: binutils, gdb, gcc

On Wed, 20 Mar 2024 at 16:34, Simon Marchi <simark@simark.ca> wrote:
>
> On 3/18/24 13:25, Christophe Lyon wrote:
> > Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit
> > more complex
> > than just calling automake. IIUC it calls automake --foreign it any of
> > *.m4 file from $(am__configure_deps) that is newer than Makefile.in
> > (with an early exit in the loop), does nothing if Makefile.am or
> > doc/local.mk are newer than Makefile.in, and then calls 'automake
> > --foreign Makefile'
>
> The rules looks complex because they've been generated by automake, this
> Makefile.in is not written by hand.  And I guess automake has put
> `--foreign` there because foreign is used in Makefile.am:
Yes, I know :-)

>
>   AUTOMAKE_OPTIONS = foreign no-dist
>
> But a simple call so `automake -f` (or `autoreconf -f`) just works, as
> automake picks up the foreign option from AUTOMAKE_OPTIONS, so a human
> or an external script who wants to regenerate things would probably just
> use that.

Indeed. I guess my concern is: if some change happens to
Makefile.am/Makefile.in which would imply that 'autoreconf -f' would
not work, how do we make sure autoregen.py (or whatever script) is
updated accordingly? Or maybe whatever change is made to
Makefile.am/Makefile.in, 'autoreconf -f' is supposed to handle it
without additional flag?

>
> > The bot I want to put in place would regenerate things as they are
> > supposed to be, then build and run the testsuite to make sure that
> > what is supposed to be committed would work (if the committer
> > regenerates everything correctly)
>
> For your job, would it be fine to just force-regenerate everything and
> ignore timestamps (just like the buildbot's autoregen job wants to do)?
> It would waste a few cycles, but it would be much simpler.
>
Yes, that would achieve the purpose: be able to handle as many patches
as possible in precommit-CI.
And as described earlier, for binutils this currently means:
autoregen
confgure --enable-maintainer-mode
make all (with a low -j value otherwise we have random build failures)
and my proposal to workaround the problem with -j is to do
make all-bfd all-libiberty regenerate -j1
make all -j XXX

Another possibility would be a policy change in how patches are
submitted, to require that they contain all the autogenerated files.


> Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-21 14:32           ` Christophe Lyon
@ 2024-03-25 14:19             ` Christophe Lyon
  2024-03-27 18:22               ` Christophe Lyon
  2024-04-08  9:22               ` Christophe Lyon
  0 siblings, 2 replies; 21+ messages in thread
From: Christophe Lyon @ 2024-03-25 14:19 UTC (permalink / raw)
  To: Simon Marchi; +Cc: binutils, gdb, gcc

On Thu, 21 Mar 2024 at 15:32, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
>
> On Wed, 20 Mar 2024 at 16:34, Simon Marchi <simark@simark.ca> wrote:
> >
> > On 3/18/24 13:25, Christophe Lyon wrote:
> > > Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit
> > > more complex
> > > than just calling automake. IIUC it calls automake --foreign it any of
> > > *.m4 file from $(am__configure_deps) that is newer than Makefile.in
> > > (with an early exit in the loop), does nothing if Makefile.am or
> > > doc/local.mk are newer than Makefile.in, and then calls 'automake
> > > --foreign Makefile'
> >
> > The rules looks complex because they've been generated by automake, this
> > Makefile.in is not written by hand.  And I guess automake has put
> > `--foreign` there because foreign is used in Makefile.am:
> Yes, I know :-)
>
> >
> >   AUTOMAKE_OPTIONS = foreign no-dist
> >
> > But a simple call so `automake -f` (or `autoreconf -f`) just works, as
> > automake picks up the foreign option from AUTOMAKE_OPTIONS, so a human
> > or an external script who wants to regenerate things would probably just
> > use that.
>
> Indeed. I guess my concern is: if some change happens to
> Makefile.am/Makefile.in which would imply that 'autoreconf -f' would
> not work, how do we make sure autoregen.py (or whatever script) is
> updated accordingly? Or maybe whatever change is made to
> Makefile.am/Makefile.in, 'autoreconf -f' is supposed to handle it
> without additional flag?
>
I think I've just noticed a variant of this: if you look at
opcodes/Makefile.in, you can see that aclocal.m4 depends on
configure.ac (among others). So if configure.ac is updated, a
maintainer-mode rule in Makefile.in will call aclocal and regenerate
aclocal.m4.

However, autoregen.py calls aclocal only if configure.ac contains
AC_CONFIG_MACRO_DIRS, which is not the case here.

That's probably a bug in opcode/configure.ac, but still the current
Makefile.in machinery would update aclocal.m4 as needed when
autoregen.py will not.

I haven't audited all configure.ac but there are probably other
occurrences of this.

Christophe

> >
> > > The bot I want to put in place would regenerate things as they are
> > > supposed to be, then build and run the testsuite to make sure that
> > > what is supposed to be committed would work (if the committer
> > > regenerates everything correctly)
> >
> > For your job, would it be fine to just force-regenerate everything and
> > ignore timestamps (just like the buildbot's autoregen job wants to do)?
> > It would waste a few cycles, but it would be much simpler.
> >
> Yes, that would achieve the purpose: be able to handle as many patches
> as possible in precommit-CI.
> And as described earlier, for binutils this currently means:
> autoregen
> confgure --enable-maintainer-mode
> make all (with a low -j value otherwise we have random build failures)
> and my proposal to workaround the problem with -j is to do
> make all-bfd all-libiberty regenerate -j1
> make all -j XXX
>
> Another possibility would be a policy change in how patches are
> submitted, to require that they contain all the autogenerated files.
>
>
> > Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
       [not found]     ` <78f1d113-f8ac-4a76-8dea-9f92519c1a89@linux.ibm.com>
@ 2024-03-27 18:14       ` Christophe Lyon
  2024-03-28  8:55         ` Jens Remus
  0 siblings, 1 reply; 21+ messages in thread
From: Christophe Lyon @ 2024-03-27 18:14 UTC (permalink / raw)
  To: Jens Remus; +Cc: Simon Marchi, binutils, gdb, GCC Mailing List

On Tue, 26 Mar 2024 at 16:42, Jens Remus <jremus@linux.ibm.com> wrote:
>
> Am 15.03.2024 um 09:50 schrieb Christophe Lyon:
> > On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
> >> On 2024-03-13 04:02, Christophe Lyon via Gdb wrote:
> ...
> >> There's just the issue of files that are generated using tools that are
> >> compiled.  When experimenting with maintainer mode the other day, I
> >> stumbled on the opcodes/i386-gen, for instance.  I don't have a good
> >> solution to that, except to rewrite these tools in a scripting language
> >> like Python.
> >
> > So for opcodes, it currently means rewriting such programs for i386,
> > aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
> > generator.
> > Not sure how to find volunteers?
>
> Why are those generated source files checked into the repository and not
> generated at build-time? Would there be a reason for s390 do so as well
> (opcodes/s390-opc.tab is generated at build-time from
> opcodes/s390-opc.txt using s390-mkopc built from opcodes/s390-mkopc.c)?
>
I remember someone mentioned a requirement of being able to rebuild
with the sources on a read-only filesystem.
I don't know if there's a requirement that such generated files should
be part of the source tree though. Is opcodes/s390-opc.tab in builddir
or in srcdir?

I think there are other motivations but I can't remember them at the moment :-)

Thanks,

Christophe

> Thanks and regards,
> Jens
> --
> Jens Remus
> Linux on Z Development (D3303) and z/VSE Support
> +49-7031-16-1128 Office
> jremus@de.ibm.com
>
> IBM
>
> IBM Deutschland Research & Development GmbH; Vorsitzender des
> Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der
> Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
> IBM Data Privacy Statement: https://www.ibm.com/privacy/

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-25 14:19             ` Christophe Lyon
@ 2024-03-27 18:22               ` Christophe Lyon
  2024-04-08  9:22               ` Christophe Lyon
  1 sibling, 0 replies; 21+ messages in thread
From: Christophe Lyon @ 2024-03-27 18:22 UTC (permalink / raw)
  To: Simon Marchi; +Cc: binutils, gdb, gcc

Hi!


On Mon, 25 Mar 2024 at 15:19, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
>
> On Thu, 21 Mar 2024 at 15:32, Christophe Lyon
> <christophe.lyon@linaro.org> wrote:
> >
> > On Wed, 20 Mar 2024 at 16:34, Simon Marchi <simark@simark.ca> wrote:
> > >
> > > On 3/18/24 13:25, Christophe Lyon wrote:
> > > > Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit
> > > > more complex
> > > > than just calling automake. IIUC it calls automake --foreign it any of
> > > > *.m4 file from $(am__configure_deps) that is newer than Makefile.in
> > > > (with an early exit in the loop), does nothing if Makefile.am or
> > > > doc/local.mk are newer than Makefile.in, and then calls 'automake
> > > > --foreign Makefile'
> > >
> > > The rules looks complex because they've been generated by automake, this
> > > Makefile.in is not written by hand.  And I guess automake has put
> > > `--foreign` there because foreign is used in Makefile.am:
> > Yes, I know :-)
> >
> > >
> > >   AUTOMAKE_OPTIONS = foreign no-dist
> > >
> > > But a simple call so `automake -f` (or `autoreconf -f`) just works, as
> > > automake picks up the foreign option from AUTOMAKE_OPTIONS, so a human
> > > or an external script who wants to regenerate things would probably just
> > > use that.
> >
> > Indeed. I guess my concern is: if some change happens to
> > Makefile.am/Makefile.in which would imply that 'autoreconf -f' would
> > not work, how do we make sure autoregen.py (or whatever script) is
> > updated accordingly? Or maybe whatever change is made to
> > Makefile.am/Makefile.in, 'autoreconf -f' is supposed to handle it
> > without additional flag?
> >
> I think I've just noticed a variant of this: if you look at
> opcodes/Makefile.in, you can see that aclocal.m4 depends on
> configure.ac (among others). So if configure.ac is updated, a
> maintainer-mode rule in Makefile.in will call aclocal and regenerate
> aclocal.m4.
>
> However, autoregen.py calls aclocal only if configure.ac contains
> AC_CONFIG_MACRO_DIRS, which is not the case here.
>
> That's probably a bug in opcode/configure.ac, but still the current
> Makefile.in machinery would update aclocal.m4 as needed when
> autoregen.py will not.
>
> I haven't audited all configure.ac but there are probably other
> occurrences of this.
>

As another follow-up on this topic, while working on a tentative GCC
patch to implement this, I realized an obvious issue: all target
libraries configure steps depend on 'all-gcc' (of course, we need a
compiler to build the libs...)

So they idea of doing roughly:
- configure --enable-maintainer-mode
- make regenerate -j1  (to avoid current race conditions in maintainer-mode)
- make all -jXXX

means that the regenerate step will trigger the configure step for all
host and target subdirs as needed, and configuring target-libs
requires building 'all-gcc', which would happen at -j1 !

sigh :-)

Looks like we should handle binutils, gdb, and gcc differently for the
sake of precommit CI.

Thanks,

Christophe



> Christophe
>
> > >
> > > > The bot I want to put in place would regenerate things as they are
> > > > supposed to be, then build and run the testsuite to make sure that
> > > > what is supposed to be committed would work (if the committer
> > > > regenerates everything correctly)
> > >
> > > For your job, would it be fine to just force-regenerate everything and
> > > ignore timestamps (just like the buildbot's autoregen job wants to do)?
> > > It would waste a few cycles, but it would be much simpler.
> > >
> > Yes, that would achieve the purpose: be able to handle as many patches
> > as possible in precommit-CI.
> > And as described earlier, for binutils this currently means:
> > autoregen
> > confgure --enable-maintainer-mode
> > make all (with a low -j value otherwise we have random build failures)
> > and my proposal to workaround the problem with -j is to do
> > make all-bfd all-libiberty regenerate -j1
> > make all -j XXX
> >
> > Another possibility would be a policy change in how patches are
> > submitted, to require that they contain all the autogenerated files.
> >
> >
> > > Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-27 18:14       ` Christophe Lyon
@ 2024-03-28  8:55         ` Jens Remus
  0 siblings, 0 replies; 21+ messages in thread
From: Jens Remus @ 2024-03-28  8:55 UTC (permalink / raw)
  To: Christophe Lyon
  Cc: Simon Marchi, binutils, gdb, GCC Mailing List, Andreas Krebbel

Am 27.03.2024 um 19:14 schrieb Christophe Lyon:
> On Tue, 26 Mar 2024 at 16:42, Jens Remus <jremus@linux.ibm.com> wrote:
>> Am 15.03.2024 um 09:50 schrieb Christophe Lyon:
>>> On Thu, 14 Mar 2024 at 19:10, Simon Marchi <simark@simark.ca> wrote:
>>>> On 2024-03-13 04:02, Christophe Lyon via Gdb wrote:
>> ...
>>>> There's just the issue of files that are generated using tools that are
>>>> compiled.  When experimenting with maintainer mode the other day, I
>>>> stumbled on the opcodes/i386-gen, for instance.  I don't have a good
>>>> solution to that, except to rewrite these tools in a scripting language
>>>> like Python.
>>>
>>> So for opcodes, it currently means rewriting such programs for i386,
>>> aarch64, ia64 and luckily msp430/rl78/rx share the same opc2c
>>> generator.
>>> Not sure how to find volunteers?
>>
>> Why are those generated source files checked into the repository and not
>> generated at build-time? Would there be a reason for s390 do so as well
>> (opcodes/s390-opc.tab is generated at build-time from
>> opcodes/s390-opc.txt using s390-mkopc built from opcodes/s390-mkopc.c)?
>>
> I remember someone mentioned a requirement of being able to rebuild
> with the sources on a read-only filesystem.
> I don't know if there's a requirement that such generated files should
> be part of the source tree though. Is opcodes/s390-opc.tab in builddir
> or in srcdir?
> 
> I think there are other motivations but I can't remember them at the moment :-)

Thank you for the insights, Christophe! opcodes/s390-opc.tab is 
generated in builddir.

Regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303) and z/VSE Support
+49-7031-16-1128 Office
jremus@de.ibm.com

IBM

IBM Deutschland Research & Development GmbH; Vorsitzender des 
Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der 
Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC] add regenerate Makefile target
  2024-03-25 14:19             ` Christophe Lyon
  2024-03-27 18:22               ` Christophe Lyon
@ 2024-04-08  9:22               ` Christophe Lyon
  1 sibling, 0 replies; 21+ messages in thread
From: Christophe Lyon @ 2024-04-08  9:22 UTC (permalink / raw)
  To: Simon Marchi; +Cc: binutils, gdb, gcc

Hi,

On Mon, 25 Mar 2024 at 15:19, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
>
> On Thu, 21 Mar 2024 at 15:32, Christophe Lyon
> <christophe.lyon@linaro.org> wrote:
> >
> > On Wed, 20 Mar 2024 at 16:34, Simon Marchi <simark@simark.ca> wrote:
> > >
> > > On 3/18/24 13:25, Christophe Lyon wrote:
> > > > Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit
> > > > more complex
> > > > than just calling automake. IIUC it calls automake --foreign it any of
> > > > *.m4 file from $(am__configure_deps) that is newer than Makefile.in
> > > > (with an early exit in the loop), does nothing if Makefile.am or
> > > > doc/local.mk are newer than Makefile.in, and then calls 'automake
> > > > --foreign Makefile'
> > >
> > > The rules looks complex because they've been generated by automake, this
> > > Makefile.in is not written by hand.  And I guess automake has put
> > > `--foreign` there because foreign is used in Makefile.am:
> > Yes, I know :-)
> >
> > >
> > >   AUTOMAKE_OPTIONS = foreign no-dist
> > >
> > > But a simple call so `automake -f` (or `autoreconf -f`) just works, as
> > > automake picks up the foreign option from AUTOMAKE_OPTIONS, so a human
> > > or an external script who wants to regenerate things would probably just
> > > use that.
> >
> > Indeed. I guess my concern is: if some change happens to
> > Makefile.am/Makefile.in which would imply that 'autoreconf -f' would
> > not work, how do we make sure autoregen.py (or whatever script) is
> > updated accordingly? Or maybe whatever change is made to
> > Makefile.am/Makefile.in, 'autoreconf -f' is supposed to handle it
> > without additional flag?
> >
> I think I've just noticed a variant of this: if you look at
> opcodes/Makefile.in, you can see that aclocal.m4 depends on
> configure.ac (among others). So if configure.ac is updated, a
> maintainer-mode rule in Makefile.in will call aclocal and regenerate
> aclocal.m4.
>
> However, autoregen.py calls aclocal only if configure.ac contains
> AC_CONFIG_MACRO_DIRS, which is not the case here.
>
> That's probably a bug in opcode/configure.ac, but still the current
> Makefile.in machinery would update aclocal.m4 as needed when
> autoregen.py will not.
>
> I haven't audited all configure.ac but there are probably other
> occurrences of this.
>

Another discrepancy I've just noticed: if you look at libsframe/Makefile.am,
you can see that ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd,
so if you run autoreconf -f, it will invoke aclocal with these flags
(the same is performed by the aclocal.m4 regeneration rule in the Makefile),
but autoregen.py won't run aclocal because configure.ac does not define
AC_CONFIG_MACRO_DIRS, and even if it did, it would only use -I../config

I guess the same applies for several other subdirs.

So in general how do we make sure autoregen.py uses the right flags?

Or what prevents us from just using autoreconf -f? If that does not work
because configure.ac/Makeline.am and others have bugs, maybe
we should fix those bugs instead?

which makes me think about Eric's reply:

> `autoreconf -f` works fine in individual subdirectories, the problem
> is that the top-level configure.ac doesn't use the AC_CONFIG_SUBDIRS
> macro to specify its subdirectories, but rather uses its own
> hand-rolled method of specifying subdirectories that autoreconf
> doesn't know about. This means that autoreconf won't automatically
> recurse into all the necessary subdirectories by itself automatically,
> and instead has to be run manually in each subdirectory separately.

It's not clear to me if that "problem" is a bug, or a design decision
we must take into account when writing tools to help regeneration?

> Also the various subdirectories are inconsistent about whether they
> have a rule for running it (autoreconf) from the Makefile or not,
should that be considered a bug, and fixed?

> which usually comes down to whether the subdirectory uses automake for
> its Makefile or not (the top-level Makefile doesn't; it uses its own
> weird autogen-based regeneration method instead, which means that it
> misses out on all the built-in rules that automake would implicitly
> generate, including ones related to build system regeneration).

Thanks,

Christophe


> Christophe
>
> > >
> > > > The bot I want to put in place would regenerate things as they are
> > > > supposed to be, then build and run the testsuite to make sure that
> > > > what is supposed to be committed would work (if the committer
> > > > regenerates everything correctly)
> > >
> > > For your job, would it be fine to just force-regenerate everything and
> > > ignore timestamps (just like the buildbot's autoregen job wants to do)?
> > > It would waste a few cycles, but it would be much simpler.
> > >
> > Yes, that would achieve the purpose: be able to handle as many patches
> > as possible in precommit-CI.
> > And as described earlier, for binutils this currently means:
> > autoregen
> > confgure --enable-maintainer-mode
> > make all (with a low -j value otherwise we have random build failures)
> > and my proposal to workaround the problem with -j is to do
> > make all-bfd all-libiberty regenerate -j1
> > make all -j XXX
> >
> > Another possibility would be a policy change in how patches are
> > submitted, to require that they contain all the autogenerated files.
> >
> >
> > > Simon

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2024-04-08  9:22 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-13  8:02 [RFC] add regenerate Makefile target Christophe Lyon
2024-03-14 18:10 ` Simon Marchi
2024-03-15  8:50   ` Christophe Lyon
2024-03-15 14:13     ` Eric Gallager
2024-03-15 14:25       ` Tom Tromey
2024-03-16 17:30         ` Simon Marchi
2024-03-18 17:28         ` Christophe Lyon
2024-03-20 15:11           ` Simon Marchi
2024-03-18 16:13       ` Christophe Lyon
2024-03-16 17:16     ` Simon Marchi
2024-03-18 17:25       ` Christophe Lyon
2024-03-19 17:11         ` Christophe Lyon
2024-03-19 18:03           ` Tom Tromey
2024-03-20 12:05             ` Eric Gallager
2024-03-20 15:34         ` Simon Marchi
2024-03-21 14:32           ` Christophe Lyon
2024-03-25 14:19             ` Christophe Lyon
2024-03-27 18:22               ` Christophe Lyon
2024-04-08  9:22               ` Christophe Lyon
     [not found]     ` <78f1d113-f8ac-4a76-8dea-9f92519c1a89@linux.ibm.com>
2024-03-27 18:14       ` Christophe Lyon
2024-03-28  8:55         ` Jens Remus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).