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

Reply via email to