# Makefile for regression testing the GNU debugger.
# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003, 2004,
# 2005, 2007, 2008, 2009 Free Software Foundation, Inc.

# This file is part of GDB.

# GDB is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# GDB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

VPATH = @srcdir@
srcdir = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@

target_alias = @target_noncanonical@
program_transform_name = @program_transform_name@
build_canonical = @build@
host_canonical = @host@
target_canonical = @target@

SHELL = @SHELL@
EXEEXT = @EXEEXT@
SUBDIRS = @subdirs@
RPATH_ENVVAR = @RPATH_ENVVAR@
ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.cp gdb.disasm \
	gdb.dwarf2 \
	gdb.fortran gdb.server gdb.java gdb.mi \
	gdb.objc gdb.opt gdb.pascal gdb.python gdb.threads gdb.trace \
	gdb.xml \
	$(SUBDIRS)

EXPECT = `if [ -f $${rootme}/../../expect/expect ] ; then \
          echo $${rootme}/../../expect/expect ; \
          else echo expect ; fi`

RUNTEST = $(RUNTEST_FOR_TARGET)

RUNTESTFLAGS =

FORCE_PARALLEL =

RUNTEST_FOR_TARGET = `\
  if [ -f $${srcdir}/../../dejagnu/runtest ]; then \
    echo $${srcdir}/../../dejagnu/runtest; \
  else \
    if [ "$(host_canonical)" = "$(target_canonical)" ]; then \
      echo runtest; \
    else \
      t='$(program_transform_name)'; echo runtest | sed -e $$t; \
    fi; \
  fi`

#### host, target, and site specific Makefile frags come in here.

# The use of $$(x_FOR_TARGET) reduces the command line length by not
# duplicating the lengthy definition.

TARGET_FLAGS_TO_PASS = \
        "prefix=$(prefix)" \
        "exec_prefix=$(exec_prefix)" \
        "against=$(against)" \
        'CC=$$(CC_FOR_TARGET)' \
        "CC_FOR_TARGET=$(CC_FOR_TARGET)" \
        "CFLAGS=$(TESTSUITE_CFLAGS)" \
        'CXX=$$(CXX_FOR_TARGET)' \
        "CXX_FOR_TARGET=$(CXX_FOR_TARGET)" \
        "CXXFLAGS=$(CXXFLAGS)" \
        "MAKEINFO=$(MAKEINFO)" \
        "INSTALL=$(INSTALL)" \
        "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
        "INSTALL_DATA=$(INSTALL_DATA)" \
        "LDFLAGS=$(LDFLAGS)" \
        "LIBS=$(LIBS)" \
        "RUNTEST=$(RUNTEST)" \
        "RUNTESTFLAGS=$(RUNTESTFLAGS)"

all:
	@echo "Nothing to be done for all..."

.NOEXPORT:
INFODIRS=doc
info:
install-info:
dvi:
pdf:
install-pdf:
html:
install-html:

install:

uninstall: force

site.exp: ./config.status Makefile
	@echo "Making a new config file..."
	-@rm -f ./tmp?
	@touch site.exp
	-@mv site.exp site.bak
	@echo "## these variables are automatically generated by make ##" > ./tmp0
	@echo "# Do not edit here. If you wish to override these values" >> ./tmp0
	@echo "# add them to the last section" >> ./tmp0
	@echo "set host_triplet ${host_canonical}" >> ./tmp0
	@echo "set target_alias $(target_alias)" >> ./tmp0
	@echo "set target_triplet ${target_canonical}" >> ./tmp0
	@echo "set build_triplet ${build_canonical}" >> ./tmp0
	@echo "set srcdir ${srcdir}" >> ./tmp0
	@echo "set tool gdb" >> ./tmp0
	@echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0
		@cat ./tmp0 > site.exp
	@cat site.bak | sed \
			-e '1,/^## All variables above are.*##/ d' >> site.exp
	-@rm -f ./tmp?

installcheck:

# For GNU make, try to run the tests in parallel.  If RUNTESTFLAGS is
# not empty, then by default the tests will be serialized.  This can
# be overridden by setting FORCE_PARALLEL to any non-empty value.
# For a non-GNU make, do not parallelize.
@GMAKE_TRUE@CHECK_TARGET = $(if $(FORCE_PARALLEL),check-parallel,$(if $(RUNTESTFLAGS),check-single,check-parallel))
@GMAKE_FALSE@CHECK_TARGET = check-single

check: $(CHECK_TARGET)

# All the hair to invoke dejagnu.  A given invocation can just append
# $(RUNTESTFLAGS)
DO_RUNTEST = \
	rootme=`pwd`; export rootme; \
	srcdir=${srcdir} ; export srcdir ; \
	EXPECT=${EXPECT} ; export EXPECT ; \
	EXEEXT=${EXEEXT} ; export EXEEXT ; \
        $(RPATH_ENVVAR)=$$rootme/../../expect:$$rootme/../../libstdc++:$$rootme/../../tk/unix:$$rootme/../../tcl/unix:$$rootme/../../bfd:$$rootme/../../opcodes:$$$(RPATH_ENVVAR); \
	export $(RPATH_ENVVAR); \
	if [ -f $${rootme}/../../expect/expect ] ; then  \
	  TCL_LIBRARY=$${srcdir}/../../tcl/library ; \
	  export TCL_LIBRARY ; fi ; \
	$(RUNTEST)

check-single: all site.exp
	$(DO_RUNTEST) $(RUNTESTFLAGS)

# A list of all directories named "gdb.*" which also hold a .exp file.
# We filter out gdb.base and add fake entries, because that directory
# takes the longest to process, and so we split it in half.
TEST_DIRS = gdb.base1 gdb.base2 $(filter-out gdb.base,$(sort $(notdir $(patsubst %/,%,$(dir $(wildcard $(srcdir)/gdb.*/*.exp))))))

TEST_TARGETS = $(addprefix check-,$(TEST_DIRS))

# We explicitly re-invoke make here for two reasons.  First, it lets
# us add a -k option, which makes the parallel check mimic the
# behavior of the serial check; and second, it means that we can still
# regenerate the sum and log files even if a sub-make fails -- which
# it usually does because dejagnu exits with an error if any test
# fails.
check-parallel:
	$(MAKE) -k $(TEST_TARGETS); \
	$(SHELL) $(srcdir)/dg-extract-results.sh \
	  $(addsuffix /gdb.sum,$(TEST_DIRS)) > gdb.sum; \
	$(SHELL) $(srcdir)/dg-extract-results.sh -L \
	  $(addsuffix /gdb.log,$(TEST_DIRS)) > gdb.log

$(filter-out check-gdb.base%,$(TEST_TARGETS)): check-gdb.%: all site.exp
	@if test ! -d gdb.$*; then mkdir gdb.$*; fi
	$(DO_RUNTEST) --directory=gdb.$* --outdir=gdb.$* $(RUNTESTFLAGS)

# Each half (roughly) of the .exp files from gdb.base.
BASE1_FILES = $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/gdb.base/[a-m]*.exp))
BASE2_FILES = $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/gdb.base/[n-z]*.exp))

# Handle each half of gdb.base.
check-gdb.base%: all site.exp
	@if test ! -d gdb.base$*; then mkdir gdb.base$*; fi
	$(DO_RUNTEST) $(BASE$*_FILES) --outdir gdb.base$* $(RUNTESTFLAGS)

subdir_do: force
	@for i in $(DODIRS); do \
		if [ -d ./$$i ] ; then \
			if (rootme=`pwd`/ ; export rootme ; \
			    rootsrc=`cd $(srcdir); pwd`/ ; export rootsrc ; \
				cd ./$$i; \
				$(MAKE) $(TARGET_FLAGS_TO_PASS) $(DO)) ; then true ; \
			else exit 1 ; fi ; \
		else true ; fi ; \
	done

force:;

subdirs:
	for dir in ${ALL_SUBDIRS} ; \
	do \
		echo "$$dir:" ; \
		if [ -d $$dir ] ; then \
			(rootme=`pwd`/ ; export rootme ; \
			 rootsrc=`cd $(srcdir); pwd`/ ; export rootsrc ; \
			 cd $$dir; $(MAKE) $(TARGET_FLAGS_TO_PASS)); \
		fi; \
	done

clean mostlyclean:
	-rm -f *~ core *.o a.out xgdb *.x *.grt
	if [ x"${ALL_SUBDIRS}" != x ] ; then \
	    for dir in ${ALL_SUBDIRS}; \
	    do \
		    echo "$$dir:"; \
		    if [ -d $$dir ]; then \
			    (cd $$dir; $(MAKE) clean); \
		    fi; \
	    done ; \
	else true; fi

distclean maintainer-clean realclean: clean
	-rm -f *~ core
	-rm -f Makefile config.status *-init.exp
	-rm -fr *.log summary detail *.plog *.sum *.psum site.*
	if [ x"${ALL_SUBDIRS}" != x ] ; then \
	    for dir in ${ALL_SUBDIRS}; \
	    do \
		    echo "$$dir:"; \
		    if [ -d $$dir ]; then \
			    (cd $$dir; $(MAKE) distclean); \
		    fi; \
	    done ; \
	else true; fi

Makefile : Makefile.in config.status $(host_makefile_frag)
	$(SHELL) config.status

config.status: configure
	$(SHELL) config.status --recheck
