# Makefile for regression testing the GNU debugger.
# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
# 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@

host_alias = @host_alias@
target_alias = @target_alias@
program_transform_name = @program_transform_name@
build_canonical = @build@
host_canonical = @host@
target_canonical = @target@
target_cpu = @gdb_target_cpu@

SHELL = @SHELL@
EXEEXT = @EXEEXT@
SUBDIRS = @subdirs@
RPATH_ENVVAR = @RPATH_ENVVAR@

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

RUNTEST = $(RUNTEST_FOR_TARGET)

RUNTESTFLAGS =

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)" \
        "CHILLFLAGS=$(CHILLFLAGS)" \
        'CHILL=$$(CHILL_FOR_TARGET)' \
        "CHILL_FOR_TARGET=$(CHILL_FOR_TARGET)" \
        "CHILL_LIB=$(CHILL_LIB)" \
        '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:
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_alias $(host_alias)" >> ./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:

check: site.exp all just-check

just-check:
	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) $(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 ${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"${SUBDIRS}" != x ] ; then \
	    for dir in ${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"${SUBDIRS}" != x ] ; then \
	    for dir in ${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) $(target_makefile_frag)
	$(SHELL) config.status

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