Hi!

I'd like to add selftests for an aspect of the GCC/nvptx back end's
multilib configuration, outside of the language front ends: at
Makefile/shell level.  Looking into GCC's selftest implementation,
I found one issue to potentially refactor:

On 2018-10-13T09:12:03-0400, David Malcolm <dmalc...@redhat.com> wrote:
> On Fri, 2018-10-12 at 14:17 -0400, David Malcolm wrote:
>> On Fri, 2018-10-12 at 14:45 -0400, David Malcolm wrote:
>> > On Thu, 2017-07-06 at 20:58 +0200, Jakub Jelinek wrote:
>> > > > [want to run selftests only for selected languages]
>> > >
>> > > You should do something similar for how we make check etc.:
>> > > CHECK_TARGETS = @check_languages@
>> > >
>> > > check: $(CHECK_TARGETS)
>> > >
>> > > and then each Make-lang.in defining its check-<lang> goal.
>> > > So similarly to that s-selftest-c++ should be in cp/Make-lang.in
>> > > and based on the configured languages should include the 
>> > > s-selftest-<lang>
>> > > dependencies.

>> > I attemped the above, but it required each Make-lang.in to define
>> > a check-<lang> goal, but there are only two that make sense to run
>> > (those that set LANG_HOOKS_RUN_LANG_SELFTESTS: C and C++).
>> >
>> > Rather than add one to every Make-lang.in, I borrowing the "append"
>> > approach used by "lang_checks", so that only the Make-lang.in files
>> > that opt-in to having selftests need to do anything, appending
>> > their s-selftest-<LANG> to lang_selftests.

I did wonder why we don't simply define what the GNU Make manual calls
"Multiple Rules for One Target", that is, in each 'Make-lang.in' where we
want to run selftests (not in all 'Make-lang.in' files!), we define:

    selftest: s-selftest-[lang]
    
    s-selftest-[lang]: $([LANG]_SELFTEST_DEPS)
        [invoke]
        $(STAMP) $@

..., and then 'make selftest' would invoke these for all selected
languages.  However, it's not that simple, because:

>> Sorry; I failed to properly check the case Steve ran into back in July,
>> and my patch doesn't handle it (all of the Make-lang.in files are
>> included, regardless of configuration, via LANG_MAKEFRAGS).

... due to that last statement (in parens).  However:

> Here's an updated version; sorry for the earlier noise.
>
> This one follows the approach you suggested, adding a SELFTEST_TARGETS
> built from a configure-supplied selftest_languages.  Each Make-lang.in
> defines a selftest-LANG, which becomes a dependency of "selftest".
> Almost all of the selftest-LANG are empty, apart from those for c and c++.

Instead of inventing a new mechanism like this, couldn't we route the
languages' selftest rules via a new 'Make-hooks' target, which the
top-level 'selftest' target would depend on: 'lang.selftest'?  That one
would list '[lang].selftest' only for all selected languages, and that
way, we avoid the need to propagate 'selftest_languages' via 'configure',
as we're currently doing (see below).  OK if I try to make that work?


Now my actual question: again referring to what the GNU Make manual calls
"Multiple Rules for One Target", I suppose it's OK to do the following?

    --- gcc/config/nvptx/t-nvptx
    +++ gcc/config/nvptx/t-nvptx
    @@ -63,0 +64,7 @@ [...]
    +
    +selftest: s-selftest-nvptx_gen-multilib-matches
    +
    +s-selftest-nvptx_gen-multilib-matches: 
$(srcdir)/config/nvptx/gen-multilib-matches.sh # data_file
    +   : IMPLEMENT $@
    +   # false
    +   $(STAMP) $@

Per my quick testing, this appears to behave as expected: early in the
build, 's-selftest-nvptx_gen-multilib-matches' is run, and if there's an
error, the build fails.  (All details still to be filled in, obviously.)

This back end 'selftest' rule doesn't have the same problem as the front
end ones (the 'LANG_MAKEFRAGS' issue mentioned above), given that
'gcc/Makefile.in' doesn't 'include' all, but just the one specific
configuration's 'tmake_file's:

    [...]
    tmake_file=@tmake_file@
    [...]
    # target overrides
    -include $(tmake_file)
    [...]

I'll proceed in that way, unless anyone sees any issue with this.


Grüße
 Thomas


> gcc/ChangeLog:
>       * Makefile.in (SELFTEST_TARGETS): New.
>       (selftest) Change from s-selftest-c to $(SELFTEST_TARGETS).
>       (C_SELFTEST_FLAGS, C_SELFTEST_DEPS, s-selftest-c, selftest-c-gdb)
>       (selftest-gdb, selftest-c-valgrind, selftest-valgrind): Move to
>       c/Make-lang.in.
>       (CPP_SELFTEST_FLAGS, CPP_SELFTEST_DEPS, s-selftest-c++)
>       (selftest-c++-gdb, selftest-c++-valgrind): Move to
>       cp/Make-lang.in.
>       * configure: Regenerate.
>       * configure.ac (selftest_languages): New.
>
> gcc/brig/ChangeLog:
>       * Make-lang.in (selftest-brig): New.
>
> gcc/c/ChangeLog:
>       * Make-lang.in (selftest-c): New.
>       (C_SELFTEST_FLAGS, C_SELFTEST_DEPS, s-selftest-c, selftest-c-gdb)
>       (selftest-gdb, selftest-c-valgrind, selftest-valgrind): Move here
>       from gcc/Makefile.in.
>
> gcc/cp/ChangeLog:
>       * Make-lang.in (selftest-c++): New.
>       (CPP_SELFTEST_FLAGS, CPP_SELFTEST_DEPS, s-selftest-c++)
>       (selftest-c++-gdb, selftest-c++-valgrind): Move here from
>       gcc/Makefile.in.
>
> gcc/fortran/ChangeLog:
>       * Make-lang.in (selftest-fortran): New.
>
> gcc/go/ChangeLog:
>       * Make-lang.in (selftest-go): New.
>
> gcc/jit/ChangeLog:
>       * Make-lang.in (selftest-jit): New.
>
> gcc/lto/ChangeLog:
>       * Make-lang.in (selftest-lto): New.
>
> gcc/objc/ChangeLog:
>       * Make-lang.in (selftest-objc): New.
>
> gcc/objcp/ChangeLog:
>       * Make-lang.in (selftest-obj-c++): New.
> ---
>  gcc/Makefile.in                    | 52 
> ++++----------------------------------
>  gcc/ada/gcc-interface/Make-lang.in |  3 +++
>  gcc/brig/Make-lang.in              |  3 +++
>  gcc/c/Make-lang.in                 | 32 +++++++++++++++++++++++
>  gcc/configure                      | 12 +++++++--
>  gcc/configure.ac                   |  7 +++++
>  gcc/cp/Make-lang.in                | 26 +++++++++++++++++++
>  gcc/fortran/Make-lang.in           |  3 +++
>  gcc/go/Make-lang.in                |  3 +++
>  gcc/jit/Make-lang.in               |  3 +++
>  gcc/lto/Make-lang.in               |  3 +++
>  gcc/objc/Make-lang.in              |  3 +++
>  gcc/objcp/Make-lang.in             |  3 +++
>  13 files changed, 104 insertions(+), 49 deletions(-)
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index 116ed6e..52240d1 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -1935,62 +1935,20 @@ DEVNULL=$(if $(findstring 
> mingw,$(build)),nul,/dev/null)
>  SELFTEST_FLAGS = -nostdinc $(DEVNULL) -S -o $(DEVNULL) \
>       -fself-test=$(srcdir)/testsuite/selftests
>  
> -C_SELFTEST_FLAGS = -xc $(SELFTEST_FLAGS)
> -CPP_SELFTEST_FLAGS = -xc++ $(SELFTEST_FLAGS)
> -
>  SELFTEST_DEPS = $(GCC_PASSES) stmp-int-hdrs $(srcdir)/testsuite/selftests
>  
> -C_SELFTEST_DEPS = cc1$(exeext) $(SELFTEST_DEPS)
> -CPP_SELFTEST_DEPS = cc1plus$(exeext) $(SELFTEST_DEPS)
> -
>  # Run the selftests during the build once we have a driver and the frontend,
>  # so that self-test failures are caught as early as possible.
>  # Use "s-selftest-FE" to ensure that we only run the selftests if the
>  # driver, frontend, or selftest data change.
>  .PHONY: selftest
>  
> -# By default, only run the selftests within the C frontend
> -selftest: s-selftest-c
> -
> -# C selftests
> -s-selftest-c: $(C_SELFTEST_DEPS)
> -     $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS)
> -     $(STAMP) $@
> -
> -# Convenience methods for running C selftests under gdb:
> -.PHONY: selftest-c-gdb
> -selftest-c-gdb: $(C_SELFTEST_DEPS)
> -     $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS) \
> -       -wrapper gdb,--args
> -
> -.PHONY: selftest-gdb
> -selftest-gdb: selftest-c-gdb
> -
> -# Convenience methods for running C selftests under valgrind:
> -.PHONY: selftest-c-valgrind
> -selftest-c-valgrind: $(C_SELFTEST_DEPS)
> -     $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS) \
> -       -wrapper valgrind,--leak-check=full
> -
> -.PHONY: selftest-valgrind
> -selftest-valgrind: selftest-c-valgrind
> -
> -# C++ selftests
> -s-selftest-c++: $(CPP_SELFTEST_DEPS)
> -     $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS)
> -     $(STAMP) $@
> +# Potentially run all selftest-<LANG>.  The various <LANG>/Make-lang.in can
> +# require the selftests to be run by defining their selftest-<LANG> as
> +# s-selftest-<LANG>.  Otherwise, they should define it as empty.
>  
> -# Convenience method for running C++ selftests under gdb:
> -.PHONY: selftest-c++-gdb
> -selftest-c++-gdb: $(CPP_SELFTEST_DEPS)
> -     $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS) \
> -       -wrapper gdb,--args
> -
> -# Convenience method for running C++ selftests under valgrind:
> -.PHONY: selftest-c++-valgrind
> -selftest-c++-valgrind: $(CPP_SELFTEST_DEPS)
> -     $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS) \
> -       -wrapper valgrind,--leak-check=full
> +SELFTEST_TARGETS = @selftest_languages@
> +selftest: $(SELFTEST_TARGETS)
>  
>  # Recompile all the language-independent object files.
>  # This is used only if the user explicitly asks for it.
> diff --git a/gcc/ada/gcc-interface/Make-lang.in 
> b/gcc/ada/gcc-interface/Make-lang.in
> index 4866c2a..5602092 100644
> --- a/gcc/ada/gcc-interface/Make-lang.in
> +++ b/gcc/ada/gcc-interface/Make-lang.in
> @@ -930,6 +930,9 @@ check_gnat_parallelize = 1000
>  check-ada: check-acats check-gnat
>  check-ada-subtargets: check-acats-subtargets check-gnat-subtargets
>  
> +# No ada-specific selftests
> +selftest-ada:
> +
>  ACATSDIR = $(TESTSUITEDIR)/ada/acats
>  ACATSCMD = run_acats.sh
>  
> diff --git a/gcc/brig/Make-lang.in b/gcc/brig/Make-lang.in
> index 8799aa7..07c038c 100644
> --- a/gcc/brig/Make-lang.in
> +++ b/gcc/brig/Make-lang.in
> @@ -148,6 +148,9 @@ brig.srcman: doc/gccbrig.1
>  
>  lang_checks += check-brig
>  
> +# No brig-specific selftests
> +selftest-brig:
> +
>  # Install hooks.
>  
>  brig.install-common: installdirs
> diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
> index 180923f..bfae6fd 100644
> --- a/gcc/c/Make-lang.in
> +++ b/gcc/c/Make-lang.in
> @@ -110,6 +110,38 @@ c.tags: force
>  c.man:
>  c.srcman:
>  
> +# C selftests
> +
> +# If C is enabled, require the selftests to be run for it
> +# at each stage of the build:
> +selftest-c: s-selftest-c
> +
> +C_SELFTEST_FLAGS = -xc $(SELFTEST_FLAGS)
> +C_SELFTEST_DEPS = cc1$(exeext) $(SELFTEST_DEPS)
> +
> +# Run the C selftests:
> +s-selftest-c: $(C_SELFTEST_DEPS)
> +     $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS)
> +     $(STAMP) $@
> +
> +# Convenience methods for running C selftests under gdb:
> +.PHONY: selftest-c-gdb
> +selftest-c-gdb: $(C_SELFTEST_DEPS)
> +     $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS) \
> +       -wrapper gdb,--args
> +
> +.PHONY: selftest-gdb
> +selftest-gdb: selftest-c-gdb
> +
> +# Convenience methods for running C selftests under valgrind:
> +.PHONY: selftest-c-valgrind
> +selftest-c-valgrind: $(C_SELFTEST_DEPS)
> +     $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS) \
> +       -wrapper valgrind,--leak-check=full
> +
> +.PHONY: selftest-valgrind
> +selftest-valgrind: selftest-c-valgrind
> +
>  # List of targets that can use the generic check- rule and its // variant.
>  lang_checks += check-gcc
>  lang_checks_parallelized += check-gcc
> diff --git a/gcc/configure b/gcc/configure
> index 3e33a69..b1f0d7c 100755
> --- a/gcc/configure
> +++ b/gcc/configure
> @@ -656,6 +656,7 @@ TM_ENDIAN_CONFIG
>  tmake_file
>  xmake_file
>  cpp_install_dir
> +selftest_languages
>  check_languages
>  build_file_translate
>  build_xm_defines
> @@ -18495,7 +18496,7 @@ else
>    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
>    lt_status=$lt_dlunknown
>    cat > conftest.$ac_ext <<_LT_EOF
> -#line 18498 "configure"
> +#line 18499 "configure"
>  #include "confdefs.h"
>  
>  #if HAVE_DLFCN_H
> @@ -18601,7 +18602,7 @@ else
>    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
>    lt_status=$lt_dlunknown
>    cat > conftest.$ac_ext <<_LT_EOF
> -#line 18604 "configure"
> +#line 18605 "configure"
>  #include "confdefs.h"
>  
>  #if HAVE_DLFCN_H
> @@ -29330,6 +29331,12 @@ do
>       check_languages="$check_languages check-$language"
>  done
>  
> +selftest_languages=
> +for language in $all_selected_languages
> +do
> +     selftest_languages="$selftest_languages selftest-$language"
> +done
> +
>  # We link each language in with a set of hooks, reached indirectly via
>  # lang.${target}.  Only do so for selected languages.
>  
> @@ -29462,6 +29469,7 @@ fi
>  
>  
>  
> +
>  # Echo link setup.
>  if test x${build} = x${host} ; then
>    if test x${host} = x${target} ; then
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index ff6444a..793ca71 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -6187,6 +6187,12 @@ do
>       check_languages="$check_languages check-$language"
>  done
>  
> +selftest_languages=
> +for language in $all_selected_languages
> +do
> +     selftest_languages="$selftest_languages selftest-$language"
> +done
> +
>  # We link each language in with a set of hooks, reached indirectly via
>  # lang.${target}.  Only do so for selected languages.
>  
> @@ -6270,6 +6276,7 @@ AC_SUBST(build_xm_include_list)
>  AC_SUBST(build_xm_defines)
>  AC_SUBST(build_file_translate)
>  AC_SUBST(check_languages)
> +AC_SUBST(selftest_languages)
>  AC_SUBST(cpp_install_dir)
>  AC_SUBST(xmake_file)
>  AC_SUBST(tmake_file)
> diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
> index fa8c1e6..e358b76 100644
> --- a/gcc/cp/Make-lang.in
> +++ b/gcc/cp/Make-lang.in
> @@ -164,6 +164,32 @@ c++.man: doc/g++.1
>  c++.srcman: doc/g++.1
>       -cp -p $^ $(srcdir)/doc
>  
> +# C++ selftests
> +
> +# If C++ is enabled, require the selftests to be run for it
> +# at each stage of the build:
> +selftest-c++: s-selftest-c++
> +
> +CPP_SELFTEST_DEPS = cc1plus$(exeext) $(SELFTEST_DEPS)
> +CPP_SELFTEST_FLAGS = -xc++ $(SELFTEST_FLAGS)
> +
> +# Run the C++ selftests
> +s-selftest-c++: $(CPP_SELFTEST_DEPS)
> +     $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS)
> +     $(STAMP) $@
> +
> +# Convenience method for running C++ selftests under gdb:
> +.PHONY: selftest-c++-gdb
> +selftest-c++-gdb: $(CPP_SELFTEST_DEPS)
> +     $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS) \
> +       -wrapper gdb,--args
> +
> +# Convenience method for running C++ selftests under valgrind:
> +.PHONY: selftest-c++-valgrind
> +selftest-c++-valgrind: $(CPP_SELFTEST_DEPS)
> +     $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS) \
> +       -wrapper valgrind,--leak-check=full
> +
>  # 'make check' in gcc/ looks for check-c++, as do all toplevel C++-related
>  # check targets.  However, our DejaGNU framework requires 'check-g++' as its
>  # entry point.  We feed the former to the latter here.
> diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
> index 62f652e..5eff00b 100644
> --- a/gcc/fortran/Make-lang.in
> +++ b/gcc/fortran/Make-lang.in
> @@ -170,6 +170,9 @@ lang_checks_parallelized += check-gfortran
>  # For description see the check_$lang_parallelize comment in gcc/Makefile.in.
>  check_gfortran_parallelize = 10000
>  
> +# No fortran-specific selftests
> +selftest-fortran:
> +
>  # GFORTRAN documentation.
>  GFORTRAN_TEXI = \
>    $(srcdir)/fortran/gfortran.texi \
> diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in
> index 021250a..e8656cb 100644
> --- a/gcc/go/Make-lang.in
> +++ b/gcc/go/Make-lang.in
> @@ -139,6 +139,9 @@ lang_checks += check-go
>  lang_checks_parallelized += check-go
>  check_go_parallelize = 10
>  
> +# No go-specific selftests
> +selftest-go:
> +
>  # Install hooks.
>  
>  go.install-common: installdirs
> diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in
> index 280c094..e82f945 100644
> --- a/gcc/jit/Make-lang.in
> +++ b/gcc/jit/Make-lang.in
> @@ -270,6 +270,9 @@ lang_checks_parallelized += check-jit
>  # we want them to be placed in different "buckets".
>  check_jit_parallelize = 10
>  
> +# No jit-specific selftests
> +selftest-jit:
> +
>  #
>  # Install hooks:
>  jit.install-common: installdirs
> diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
> index 4695077..2cc3619 100644
> --- a/gcc/lto/Make-lang.in
> +++ b/gcc/lto/Make-lang.in
> @@ -86,3 +86,6 @@ lto1.fda: ../prev-gcc/lto1$(exeext) ../prev-gcc/$(PERF_DATA)
>  
>  # LTO testing is done as part of C/C++/Fortran etc. testing.
>  check-lto:
> +
> +# No LTO-specific selftests
> +selftest-lto:
> diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in
> index 49b7a9f..909a774 100644
> --- a/gcc/objc/Make-lang.in
> +++ b/gcc/objc/Make-lang.in
> @@ -98,6 +98,9 @@ lang_checks += check-objc
>  lang_checks_parallelized += check-objc
>  check_objc_parallelize = 6
>  
> +# No objc-c-specific selftests
> +selftest-objc:
> +
>  #
>  # Install hooks:
>  # cc1obj is installed elsewhere as part of $(COMPILERS).
> diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in
> index 5a03999..c98286b 100644
> --- a/gcc/objcp/Make-lang.in
> +++ b/gcc/objcp/Make-lang.in
> @@ -126,6 +126,9 @@ obj-c++.tags: force
>  
>  lang_checks += check-obj-c++
>  
> +# No objc-c++-specific selftests
> +selftest-obj-c++:
> +
>  #
>  # Install hooks:
>  # cc1objplus is installed elsewhere as part of $(COMPILERS).
> -- 
> 1.8.5.3

Reply via email to