Hi, Having rebuilt GCC with no changes relevant to Ada I saw all the gnat tests fail all of a sudden. Upon a closer inspection I have noticed that in the earlier build where tests passed `gnatmake' was invoked (in an `alpha-linux-gnu' cross-compiler build) as:
/path/to/alpha-linux/obj/gcc/gcc/gnatmake --GCC=/path/to/alpha-linux/obj/gcc/gcc/xgcc --GNATBIND=/path/to/alpha-linux/obj/gcc/gcc/gnatbind --GNATLINK=/path/to/alpha-linux/obj/gcc/gcc/gnatlink -cargs -B/path/to/alpha-linux/obj/gcc/gcc -largs --GCC=/path/to/alpha-linux/obj/gcc/gcc/xgcc -B/path/to/alpha-linux/obj/gcc/gcc -margs --RTS=/path/to/alpha-linux/obj/gcc/alpha-linux-gnu/./libada [...] while in the later one it was instead invoked as: alpha-linux-gnu-gnatmake --RTS=/path/to/alpha-linux/obj/gcc/alpha-linux-gnu/./libada [...] so rather than the uninstalled program a previously installed one from the install root in /path/to/alpha-linux/install/usr/bin was run with all the options pointing to the build tree missing, causing failures such as: FAIL: gnat.dg/abstract1.adb (test for excess errors) Excess errors: alpha-linux-gnu-gcc: fatal error: cannot execute 'gnat1': posix_spawnp: No such file or directory compilation terminated. (why `alpha-linux-gnu-gcc' couldn't find `gnat1' via a relative path to its libexec dir while it finds `cc1', etc. just fine is another matter). I have tracked down the cause to a small difference in the two build scripts that I use: one runs `make pdf' after the main build and the other one does not. The latter one makes the gnat testsuite work, while the former one causes it to fail. Now one might ask themselves: "Why would building PDF documentation matter for the gnat testsuite?" Indeed, a good question, with a surprising answer. It boils down to how uninstalled cross-gnattools are each named. There is a hook in gcc/ada/gcc-interface/Make-lang.in, which has this: ada.all.cross: for tool in $(ADA_TOOLS) ; do \ if [ -f $$tool$(exeext) ] ; \ then \ $(MV) $$tool$(exeext) $$tool-cross$(exeext); \ fi; \ done Clearly cross-gnattools are meant to be called `gnatmake-cross', etc. in their uninstalled forms and this hook is supposed to take care of it. However in a normal build of the compiler the hook is invoked too early, before gnattools have been compiled and given that it's all conditional it silently does nothing. Now upon a reinvocation of `make' to build PDF documentation gnattools will have already been built and are there in place, so the hook faithfully renames the executables as told: [...] make[4]: Nothing to be done for 'pdf'. Making pdf in mpcheck make[4]: Nothing to be done for 'pdf'. make[4]: Nothing to be done for 'pdf-am'. make[3]: Nothing to be done for 'pdf-am'. make[2]: Entering directory '/path/to/alpha-linux/obj/gcc/gcc' for tool in gnatbind gnatchop gnat gnatkr gnatlink gnatls gnatmake gnatname gnatprep gnatclean ; do \ if [ -f $tool ] ; \ then \ mv $tool $tool-cross; \ fi; \ done make[2]: Leaving directory '/path/to/alpha-linux/obj/gcc/gcc' make[1]: Entering directory '/path/to/alpha-linux/obj/gcc' [...] Oh well! And then `make install' does not care, because it has: gnat-install-tools: $(MKDIR) $(DESTDIR)$(bindir) -if [ -f gnat1$(exeext) ] ; \ then \ for tool in $(ADA_TOOLS) ; do \ install_name=`echo $$tool|sed '$(program_transform_name)'`$(exeext); \ $(RM) $(DESTDIR)$(bindir)/$$install_name; \ if [ -f $$tool-cross$(exeext) ] ; \ then \ $(INSTALL_PROGRAM) $$tool-cross$(exeext) $(DESTDIR)$(bindir)/$$install_name; \ else \ $(INSTALL_PROGRAM) $$tool$(exeext) $(DESTDIR)$(bindir)/$$install_name; \ fi ; \ done; \ $(RM) $(DESTDIR)$(bindir)/gnatdll$(exeext); \ $(INSTALL_PROGRAM) gnatdll$(exeext) $(DESTDIR)$(bindir)/gnatdll$(exeext); \ fi so it works regardless of whether the names have a `-cross' suffix or not. Then the test harness which looks for `gnatmake' in the build tree rather than `gnatmake-cross' fails to find the executable and resorts to generic `alpha-linux-gnu-gnatmake', having skipped all the logic to figure out the options pointing to the build tree. Looking for `gnatmake' rather than `gnatmake-cross' in the cross-compilation case is the second bug here. This seems like a long-standing issue as there haven't been changes in these areas since forever and I guess nobody noticed this because they didn't invoke `make pdf' or a similar target that would cause the `ada.all.cross' `make' target to trigger again after the main build. This patch addresses the issue by moving the renaming of cross-gnattools to separate `make' targets/recipes, explicitly invoked after gnattools has been built in a cross-compiler configuration, while adjusting the test harness is accordingly. I have verified with `alpha-linux-gnu' and `riscv64-linux-gnu' configurations that this works correctly. Now `gnatmake' is invoked as: /path/to/alpha-linux/obj/gcc/gcc/gnatmake-cross --GCC=/path/to/alpha-linux/obj/gcc/gcc/xgcc --GNATBIND=/path/to/alpha-linux/obj/gcc/gcc/gnatbind --GNATLINK=/path/to/alpha-linux/obj/gcc/gcc/gnatlink -cargs -B/path/to/alpha-linux/obj/gcc/gcc -largs --GCC=/path/to/alpha-linux/obj/gcc/gcc/xgcc\ -B/path/to/alpha-linux/obj/gcc/gcc\ -margs --RTS=/path/to/alpha-linux/obj/gcc/alpha-linux-gnu/./libada [...] I have also verified `powerpc64le-linux-gnu' native configuration to see no change in how `gnatmake' is called and no regressions. This has started as a two-part patch series, but then I realised that decoupling the Makefile changes from test harness updates would break testing for someone for the intermediate repository state regardless of the order the two patches would come in. While transient and unlikely to affect anyone right now, it could cause trouble with bisecting in the future. So I chose to merge them into one, even though this breaks the principle of one feature per repository change. However I also chose to retain this cover letter even though for a single patch, so as not to clutter the submission of the change itself with this lengthy discussion bringing in the context. Some of the observations made here have been necessarily repeated in the change description. Questions, comments, OK to apply? Maciej