summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-06-03 17:56:28 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-06-03 17:56:28 +0000
commit9bd3583a25565c0978504ce676e0950f6d68d3aa (patch)
tree5c53c78da56cc50a01309c41ac51c601b1386e46
parent79a161b32b413e68b9e96839c4b0d1b5b6f9ef62 (diff)
downloadfpc-9bd3583a25565c0978504ce676e0950f6d68d3aa.tar.gz
* more finegrained parallelism support for testsuite runs: the tests are no
longer split per directory, but in chunks of 100 tests (configurable via the new CHUNKSIZE=xxx Makefile parameter), which then all can be checked in parallel o dependencies between tests are handled by always putting tests whose name is the same except for the last character into the same chunk o as previously, -jx can only be used for the "all" target, other targets cannot be executed in parallel o the "units" directory has been renamed "tstunits" because otherwise "make distclean" will remove it entirely now that the main tests makefile also compiles a program git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@21479 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--tests/Makefile712
-rw-r--r--tests/Makefile.fpc117
-rw-r--r--tests/readme.txt21
-rw-r--r--tests/tstunits/MPWMake (renamed from tests/units/MPWMake)0
-rw-r--r--tests/tstunits/Makefile (renamed from tests/units/Makefile)0
-rw-r--r--tests/tstunits/Makefile.fpc (renamed from tests/units/Makefile.fpc)0
-rw-r--r--tests/tstunits/erroru.pp (renamed from tests/units/erroru.pp)0
-rw-r--r--tests/tstunits/popuperr.pp (renamed from tests/units/popuperr.pp)0
-rw-r--r--tests/tstunits/win32err.pp (renamed from tests/units/win32err.pp)0
-rw-r--r--tests/utils/concat.pp59
-rw-r--r--tests/utils/dotest.pp157
-rw-r--r--tests/utils/gparmake.pp166
12 files changed, 1102 insertions, 130 deletions
diff --git a/tests/Makefile b/tests/Makefile
index 9372027710..214728f2be 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -294,6 +294,216 @@ FPMAKE_SKIP_CONFIG=-n
FPCFPMAKE=$(FPC)
endif
endif
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+override TARGET_PROGRAMS+=gparmake
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+override TARGET_PROGRAMS+=gparmake
+endif
override INSTALL_FPCPACKAGE=y
ifdef REQUIRE_UNITSDIR
override UNITSDIR+=$(REQUIRE_UNITSDIR)
@@ -905,6 +1115,255 @@ else
TAROPT=vz
TAREXT=.tar.gz
endif
+override REQUIRE_PACKAGES=rtl
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_RTL)/$(OS_TARGET) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+ifdef UNITDIR_FPMAKE_RTL
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_RTL)
+endif
+endif
ifndef NOCPUDEF
override FPCOPTDEF=$(ARCH)
endif
@@ -1059,10 +1518,170 @@ EXECPPAS:=@$(PPAS)
endif
endif
endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override EXEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_PROGRAMS))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+override CLEANEXEDBGFILES+=$(EXEDBGFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
ifdef TARGET_RSTS
override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
override CLEANRSTFILES+=$(RSTFILES)
endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+ @$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+ $(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+ $(MAKE) all DEBUG=1
+fpc_release:
+ $(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+ $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+ $(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(PPUEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.lpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.dpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%.res: %.rc
+ windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+ $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+ $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+ @$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+ $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+ $(MKDIR) $(INSTALL_BINDIR)
+ $(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+ $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+ $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+ $(MKDIR) $(INSTALL_LIBDIR)
+ $(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+ ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+ $(MKDIR) $(INSTALL_DATADIR)
+ $(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+ $(MKDIR) $(INSTALL_SOURCEDIR)
+ $(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+ $(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+ $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
.PHONY: fpc_clean fpc_cleanall fpc_distclean
ifdef EXEFILES
override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
@@ -1247,22 +1866,23 @@ endif
fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
fpc_makefiles: fpc_makefile fpc_makefile_dirs
-debug:
-smart:
-release:
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
examples:
-shared:
-install:
-sourceinstall:
-exampleinstall:
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
distinstall:
zipinstall:
zipsourceinstall:
zipexampleinstall:
zipdistinstall:
-cleanall:
+cleanall: fpc_cleanall
makefiles: fpc_makefiles
-.PHONY: debug smart release examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall cleanall makefiles
+.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall cleanall makefiles
ifneq ($(wildcard fpcmake.loc),)
include fpcmake.loc
endif
@@ -1369,8 +1989,11 @@ export QUICKTEST
else
override TESTSUBDIRS+=$(TESTPACKAGESUBDIRS) alglib
endif
+ifndef CHUNKSIZE
+export CHUNKSIZE:=100
+endif
TESTDIRS:=test $(addprefix test/,$(TESTSUBDIRS))
-.PHONY: utils units copyfiles testprep
+.PHONY: utils tstunits copyfiles testprep
utils:
$(MAKE) -C utils utils
utilsdb:
@@ -1384,11 +2007,14 @@ endif
ifndef CONCAT
CONCAT=utils/concat
endif
+ifndef GPARMAKE
+GPARMAKE=./gparmake$(EXEEXT)
+endif
ifndef PREPUP
PREPUP=utils/prepup
endif
-units:
- $(MAKE) -C units FPC_VERSION= FPC=$(TEST_FPC) CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET) OPT="$(TEST_OPT)" CCOMPILER=$(TEST_CCOMPILER) BINUTILSPREFIX=$(TEST_BINUTILSPREFIX)
+tstunits:
+ $(MAKE) -C tstunits FPC_VERSION= FPC=$(TEST_FPC) CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET) OPT="$(TEST_OPT)" CCOMPILER=$(TEST_CCOMPILER) BINUTILSPREFIX=$(TEST_BINUTILSPREFIX)
.PHONY: create_c_objects delete_c_objects copyfiles
C_SOURCE_DIR=test/cg/obj
C_SOURCES=ctest.c tcext3.c tcext4.c tcext5.c tcext6.c
@@ -1427,9 +2053,8 @@ copyfiles: $(TEST_OUTPUTDIR)
-$(COPY) $(C_OBJECTS) $(TEST_OUTPUTDIR)/test/cg
-$(COPY) $(CPP_OBJECTS) $(TEST_OUTPUTDIR)/test/cg
-$(MKDIRTREE) $(TEST_OUTPUTDIR)/test/units/system
- $(COPY) test/units/system/test*.txt $(TEST_OUTPUTDIR)/test/units/system
testprep: testprep-stamp.$(TEST_FULL_TARGET)
-testprep-stamp.$(TEST_FULL_TARGET): utils units copyfiles
+testprep-stamp.$(TEST_FULL_TARGET): utils tstunits copyfiles
$(ECHOREDIR) $(DATE) > testprep-stamp.$(TEST_FULL_TARGET)
$(TEST_OUTPUTDIR):
$(MKDIRTREE) $@
@@ -1546,6 +2171,7 @@ ifndef SINGLEDOTESTRUNS
$(Q)$(DOTEST) $(DOTESTOPT) -e $(wildcard $(addsuffix /t*.pp,$(TESTDIRS)))
endif
alltests: alltest alltbs alltbf allwebtbs allwebtbf
+ifdef SINGLEDOTESTRUNS
.PHONY: allexectbs allexectbf allexecwebtbs allexecwebtbf allexectest allexectests
allexectbs: $(addsuffix .tbslog, $(LOGFILES))
allexectbf: $(addsuffix .tbflog, $(LOGFILES))
@@ -1555,50 +2181,50 @@ allexectest: $(addsuffix .testlog, $(LOGFILES))
$(TEST_OUTPUTDIR)/%.mergedlog : $(TEST_OUTPUTDIR)/%.testlog $(TEST_OUTPUTDIR)/%.tbslog $(TEST_OUTPUTDIR)/%.tbflog $(TEST_OUTPUTDIR)/%.webtbslog $(TEST_OUTPUTDIR)/%.webtbflog
$(Q)$(CONCAT) $^ $@
$(Q)$(COPY) $@ $(basename $@)
-$(TEST_OUTPUTDIR)/tbsdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Ltbslog -e $(sort $(wildcard tbs/t*.pp))
- $(ECHOREDIR) $(DATE) > $@
$(TEST_OUTPUTDIR)/%.tbslog : $(TBSREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.tbslog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.tbslog
-$(TEST_OUTPUTDIR)/tbfdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Ltbflog -e $(sort $(wildcard tbf/t*.pp))
- $(ECHOREDIR) $(DATE) > $@
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.tbslog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.tbslog
$(TEST_OUTPUTDIR)/%.tbflog : $(TBFREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.tbflog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.tbflog
-$(TEST_OUTPUTDIR)/webtbsdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Lwebtbslog -e $(sort $(wildcard webtbs/t*.pp))
- $(Q)$(ECHOREDIR) $(DATE) > $@
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.tbflog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.tbflog
$(TEST_OUTPUTDIR)/%.webtbslog : $(WEBTBSREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.webtbslog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.webtbslog
-$(TEST_OUTPUTDIR)/webtbfdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Lwebtbflog -e $(sort $(wildcard webtbf/t*.pp))
- $(ECHOREDIR) $(DATE) > $@
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.webtbslog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.webtbslog
$(TEST_OUTPUTDIR)/%.webtbflog : $(WEBTBFREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.webtbflog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.webtbflog
-$(TEST_OUTPUTDIR)/testdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Ltestlog -e $(sort $(wildcard $(addsuffix /t*.pp,$(TESTDIRS))))
- $(ECHOREDIR) $(DATE) > $@
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.webtbflog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.webtbflog
$(TEST_OUTPUTDIR)/%.testlog : $(TESTREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.testlog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.testlog
-allexectests: $(TEST_OUTPUTDIR)/log.webtbslog $(TEST_OUTPUTDIR)/log.testlog $(TEST_OUTPUTDIR)/log.tbslog $(TEST_OUTPUTDIR)/log.tbflog $(TEST_OUTPUTDIR)/log.webtbflog $(addprefix $(TEST_OUTPUTDIR)/,$(foreach EXT, $(LOGEXT), $(addsuffix $(EXT), faillist longlog))) $(addsuffix .mergedlog, $(LOGFILES))
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.testlog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.testlog
+allexectests: $(TEST_OUTPUTDIR)/log.testlog $(TEST_OUTPUTDIR)/log.tbslog $(TEST_OUTPUTDIR)/log.tbflog $(TEST_OUTPUTDIR)/log.webtbslog $(TEST_OUTPUTDIR)/log.webtbflog $(addprefix $(TEST_OUTPUTDIR)/,$(foreach EXT, $(LOGEXT), $(addsuffix $(EXT), faillist longlog))) $(addsuffix .mergedlog, $(LOGFILES))
+else
+.PHONY: allexectests
+$(GPARMAKE): $(COMPILER_UNITTARGETDIR) utils/gparmake.pp
+ $(FPC) $(FPC_OPT) -FE. utils/gparmake.pp
+$(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc: $(GPARMAKE) $(TEST_OUTPUTDIR)
+ $(Q)$(GPARMAKE) $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 1 $(CHUNKSIZE) $(sort $(wildcard $(addsuffix /t*.pp,$(TESTDIRS))))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 100000 $(CHUNKSIZE) $(sort $(wildcard tbs/t*.pp))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 150000 $(CHUNKSIZE) $(sort $(wildcard tbf/t*.pp))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 200000 $(CHUNKSIZE) $(sort $(wildcard webtbs/t*.pp))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 300000 $(CHUNKSIZE) $(sort $(wildcard webtbf/t*.pp))
+ifneq (,$(findstring all,$(MAKECMDGOALS)))
+include $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc
+endif
+allexectests: $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc
+endif
.PHONY: clean distclean clean_test clean_sources
clean_sources:
-$(DEL) $(wildcard $(patsubst %.pp,%$(PPUEXT),$(wildcard $(addsuffix /*.pp,$(DIRS)))))
clean_test:
-$(DELTREE) $(TEST_OUTPUTDIR)
-$(DEL) core gmon.out testprep-stamp.$(TEST_FULL_TARGET) dotgz.bat
-clean: clean_sources
+clean: clean_sources fpc_clean
$(MAKE) clean_test CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET)
- $(MAKE) -C units clean CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET)
+ $(MAKE) -C tstunits clean CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET)
distclean: clean fpc_distclean
$(DELTREE) output
$(MAKE) -C utils distclean
- $(MAKE) -C units distclean
+ $(MAKE) -C tstunits distclean
-$(DEL) testprep-stamp.*
.PHONY: all full digest onlyknown onlygraph onlyinteractive
digest : utils
diff --git a/tests/Makefile.fpc b/tests/Makefile.fpc
index 6e3335e12f..92308cb957 100644
--- a/tests/Makefile.fpc
+++ b/tests/Makefile.fpc
@@ -9,6 +9,9 @@ fpcpackage=y
fpcdir=..
rule=allexectests
+[target]
+programs=gparmake
+
[rules]
unexport FPC_VERSION
@@ -147,10 +150,15 @@ else
override TESTSUBDIRS+=$(TESTPACKAGESUBDIRS) alglib
endif
+# number of tests to run per (potentially parallel) chunk/dotest invocation
+ifndef CHUNKSIZE
+export CHUNKSIZE:=100
+endif
+
# All full dirnames in the test/ dir including the subdir self
TESTDIRS:=test $(addprefix test/,$(TESTSUBDIRS))
-.PHONY: utils units copyfiles testprep
+.PHONY: utils tstunits copyfiles testprep
################################
# Utilities
@@ -174,6 +182,10 @@ ifndef CONCAT
CONCAT=utils/concat
endif
+ifndef GPARMAKE
+GPARMAKE=./gparmake$(EXEEXT)
+endif
+
ifndef PREPUP
PREPUP=utils/prepup
endif
@@ -183,8 +195,8 @@ endif
# Units
#
-units:
- $(MAKE) -C units FPC_VERSION= FPC=$(TEST_FPC) CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET) OPT="$(TEST_OPT)" CCOMPILER=$(TEST_CCOMPILER) BINUTILSPREFIX=$(TEST_BINUTILSPREFIX)
+tstunits:
+ $(MAKE) -C tstunits FPC_VERSION= FPC=$(TEST_FPC) CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET) OPT="$(TEST_OPT)" CCOMPILER=$(TEST_CCOMPILER) BINUTILSPREFIX=$(TEST_BINUTILSPREFIX)
################################
# Copy test environment dependent files ctest.o, cext3.o, cext4.o to test/cg etc
@@ -235,14 +247,13 @@ copyfiles: $(TEST_OUTPUTDIR)
-$(COPY) $(C_OBJECTS) $(TEST_OUTPUTDIR)/test/cg
-$(COPY) $(CPP_OBJECTS) $(TEST_OUTPUTDIR)/test/cg
-$(MKDIRTREE) $(TEST_OUTPUTDIR)/test/units/system
- $(COPY) test/units/system/test*.txt $(TEST_OUTPUTDIR)/test/units/system
################################
# Preparation for tests
#
testprep: testprep-stamp.$(TEST_FULL_TARGET)
-testprep-stamp.$(TEST_FULL_TARGET): utils units copyfiles
+testprep-stamp.$(TEST_FULL_TARGET): utils tstunits copyfiles
$(ECHOREDIR) $(DATE) > testprep-stamp.$(TEST_FULL_TARGET)
$(TEST_OUTPUTDIR):
@@ -406,6 +417,7 @@ alltests: alltest alltbs alltbf allwebtbs allwebtbf
# Compile and Run tests
#
+ifdef SINGLEDOTESTRUNS
.PHONY: allexectbs allexectbf allexecwebtbs allexecwebtbf allexectest allexectests
allexectbs: $(addsuffix .tbslog, $(LOGFILES))
@@ -418,51 +430,74 @@ $(TEST_OUTPUTDIR)/%.mergedlog : $(TEST_OUTPUTDIR)/%.testlog $(TEST_OUTPUTDIR)/%.
$(Q)$(CONCAT) $^ $@
$(Q)$(COPY) $@ $(basename $@)
-# the extra ECHOREDIR's below are in case a particular dir doesn't have any failures
+$(TEST_OUTPUTDIR)/%.tbslog : $(TBSREQ)
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.tbslog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.tbslog
-$(TEST_OUTPUTDIR)/tbsdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Ltbslog -e $(sort $(wildcard tbs/t*.pp))
- $(ECHOREDIR) $(DATE) > $@
+$(TEST_OUTPUTDIR)/%.tbflog : $(TBFREQ)
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.tbflog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.tbflog
-$(TEST_OUTPUTDIR)/%.tbslog : $(TBSREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.tbslog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.tbslog
+$(TEST_OUTPUTDIR)/%.webtbslog : $(WEBTBSREQ)
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.webtbslog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.webtbslog
+
+$(TEST_OUTPUTDIR)/%.webtbflog : $(WEBTBFREQ)
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.webtbflog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.webtbflog
-$(TEST_OUTPUTDIR)/tbfdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Ltbflog -e $(sort $(wildcard tbf/t*.pp))
- $(ECHOREDIR) $(DATE) > $@
+$(TEST_OUTPUTDIR)/%.testlog : $(TESTREQ)
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/faillist.testlog
+ $(Q)$(ECHO) -n >> $(TEST_OUTPUTDIR)/longlog.testlog
-$(TEST_OUTPUTDIR)/%.tbflog : $(TBFREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.tbflog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.tbflog
+# run all tests, then merge log files
+allexectests: $(TEST_OUTPUTDIR)/log.testlog $(TEST_OUTPUTDIR)/log.tbslog $(TEST_OUTPUTDIR)/log.tbflog $(TEST_OUTPUTDIR)/log.webtbslog $(TEST_OUTPUTDIR)/log.webtbflog $(addprefix $(TEST_OUTPUTDIR)/,$(foreach EXT, $(LOGEXT), $(addsuffix $(EXT), faillist longlog))) $(addsuffix .mergedlog, $(LOGFILES))
-$(TEST_OUTPUTDIR)/webtbsdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Lwebtbslog -e $(sort $(wildcard webtbs/t*.pp))
- $(Q)$(ECHOREDIR) $(DATE) > $@
+# SINGLEDOTESTRUNS
+else
-$(TEST_OUTPUTDIR)/%.webtbslog : $(WEBTBSREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.webtbslog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.webtbslog
+.PHONY: allexectests
-$(TEST_OUTPUTDIR)/webtbfdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Lwebtbflog -e $(sort $(wildcard webtbf/t*.pp))
- $(ECHOREDIR) $(DATE) > $@
+$(GPARMAKE): $(COMPILER_UNITTARGETDIR) utils/gparmake.pp
+ $(FPC) $(FPC_OPT) -FE. utils/gparmake.pp
-$(TEST_OUTPUTDIR)/%.webtbflog : $(WEBTBFREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.webtbflog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.webtbflog
+# Can't have testprep as prerequisite, because that is a phony target and
+# phony targets are always remade. Since the makefile will be reparsed
+# after making the MakeChunks file (because it has to be included) and all
+# up-to-date checks will be re-evaluated, this means that the testprep rule
+# (or testprep timestamp file, which depends on phony rules and hence has
+# the same behaviour) will always be considered newer than the MakeChunks
+# file and hence the MakeChunks will be regenerated in an infinite loop
+# (although some make versions appear to contain a bug that prevents this
+# from happening)
+# As a result, we list TEST_OUTPUTDIR as a dependency (that just creates
+# the directory) and have an explicit rule to build GPARMAKE rather than
+# building it via the utils Makefile
+$(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc: $(GPARMAKE) $(TEST_OUTPUTDIR)
+# generate rules for parallel executions of dotest
+ $(Q)$(GPARMAKE) $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 1 $(CHUNKSIZE) $(sort $(wildcard $(addsuffix /t*.pp,$(TESTDIRS))))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 100000 $(CHUNKSIZE) $(sort $(wildcard tbs/t*.pp))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 150000 $(CHUNKSIZE) $(sort $(wildcard tbf/t*.pp))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 200000 $(CHUNKSIZE) $(sort $(wildcard webtbs/t*.pp))
+ $(Q)$(GPARMAKE) -a $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc 300000 $(CHUNKSIZE) $(sort $(wildcard webtbf/t*.pp))
-$(TEST_OUTPUTDIR)/testdir-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)
- $(Q)$(DOTEST) $(DOTESTOPT) -Ltestlog -e $(sort $(wildcard $(addsuffix /t*.pp,$(TESTDIRS))))
- $(ECHOREDIR) $(DATE) > $@
-$(TEST_OUTPUTDIR)/%.testlog : $(TESTREQ)
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/faillist.testlog
- $(Q)$(ECHOREDIR) -n >> $(TEST_OUTPUTDIR)/longlog.testlog
+# only include the targets to compile/run the tests when we want to
+# run them (in particular: not when cleaning)
+ifneq (,$(findstring all,$(MAKECMDGOALS)))
+# incude the rules we just generated
+include $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc
+endif
+
-# run all tests (ordered by longest running to shortest), then merge log files
-allexectests: $(TEST_OUTPUTDIR)/log.webtbslog $(TEST_OUTPUTDIR)/log.testlog $(TEST_OUTPUTDIR)/log.tbslog $(TEST_OUTPUTDIR)/log.tbflog $(TEST_OUTPUTDIR)/log.webtbflog $(addprefix $(TEST_OUTPUTDIR)/,$(foreach EXT, $(LOGEXT), $(addsuffix $(EXT), faillist longlog))) $(addsuffix .mergedlog, $(LOGFILES))
+# this is pretty cool: MakeChunks-$(TEST_TARGETSUFFIX).inc will contain additional prerequisites
+# for the allexectests target, and after it is generated it will be included by the above "include"
+# statement, and those additional prerquisites will be added on the fly and also be evaluated
+allexectests: $(TEST_OUTPUTDIR)/MakeChunks-$(TEST_TARGETSUFFIX).inc
+
+# SINGLEDOTESTRUNS
+endif
################################
@@ -479,14 +514,14 @@ clean_test:
-$(DELTREE) $(TEST_OUTPUTDIR)
-$(DEL) core gmon.out testprep-stamp.$(TEST_FULL_TARGET) dotgz.bat
-clean: clean_sources
+clean: clean_sources fpc_clean
$(MAKE) clean_test CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET)
- $(MAKE) -C units clean CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET)
+ $(MAKE) -C tstunits clean CPU_TARGET=$(TEST_CPU_TARGET) OS_TARGET=$(TEST_OS_TARGET)
distclean: clean fpc_distclean
$(DELTREE) output
$(MAKE) -C utils distclean
- $(MAKE) -C units distclean
+ $(MAKE) -C tstunits distclean
-$(DEL) testprep-stamp.*
#cleanall: clean
diff --git a/tests/readme.txt b/tests/readme.txt
index e796419e34..fed58977aa 100644
--- a/tests/readme.txt
+++ b/tests/readme.txt
@@ -21,6 +21,25 @@ directory. Then webtbs/webtbf/test/tbs/tbf are searched for t*.pp to be
compiled and executed as tests.
+Parallel test suite runs
+------------------------
+
+It is possible to run the test suite in parallel, but only when using the
+"all" target and only if SINGLEDOTESTRUNS is not used. Under those
+circumstances, it is safe to use -jx, with x the number of tests that can
+be compiled and run in parallel. E.g.
+
+ make all TEST_FPC=path_to_your_compiler -j 2
+
+After running the tests in parallel, you will probably want to get the
+summary. This can be achieved making the "digest" target after the "all"
+target has finished, e.g.
+
+ make digest TEST_FPC=path_to_your_compiler
+
+Make sure to clean the test suite between two runs.
+
+
Directories
-----------
webtbs...........Tests for web-bug-database bugs (should compile/run)
@@ -135,6 +154,8 @@ TEST_ABI test a certain abi, this influences where the
c object files are taken from: TEST_ABI=eabi
takes the c*.o files from
test/cg/obj/linux/arm-eabi
+CHUNKSIZE Number of tests per chunk that can be potentially executed
+ in parallel with other chunks
(Please add more test options if needed)
diff --git a/tests/units/MPWMake b/tests/tstunits/MPWMake
index 9946631a6c..9946631a6c 100644
--- a/tests/units/MPWMake
+++ b/tests/tstunits/MPWMake
diff --git a/tests/units/Makefile b/tests/tstunits/Makefile
index b8d5bce7c5..b8d5bce7c5 100644
--- a/tests/units/Makefile
+++ b/tests/tstunits/Makefile
diff --git a/tests/units/Makefile.fpc b/tests/tstunits/Makefile.fpc
index 203b59e49a..203b59e49a 100644
--- a/tests/units/Makefile.fpc
+++ b/tests/tstunits/Makefile.fpc
diff --git a/tests/units/erroru.pp b/tests/tstunits/erroru.pp
index 7e10496662..7e10496662 100644
--- a/tests/units/erroru.pp
+++ b/tests/tstunits/erroru.pp
diff --git a/tests/units/popuperr.pp b/tests/tstunits/popuperr.pp
index 0441f8810c..0441f8810c 100644
--- a/tests/units/popuperr.pp
+++ b/tests/tstunits/popuperr.pp
diff --git a/tests/units/win32err.pp b/tests/tstunits/win32err.pp
index 65d9a53ce1..65d9a53ce1 100644
--- a/tests/units/win32err.pp
+++ b/tests/tstunits/win32err.pp
diff --git a/tests/utils/concat.pp b/tests/utils/concat.pp
index 0378fcd9c7..aa24af2284 100644
--- a/tests/utils/concat.pp
+++ b/tests/utils/concat.pp
@@ -3,15 +3,20 @@
program concat;
uses
- SysUtils;
+ SysUtils, Classes;
var
Dst: TextFile;
+ FileList: TStringList;
+ IgnoreNonExisting: boolean;
procedure usage;
begin
- Writeln('Usage: concat <srcfile1> [<srcfile2> ..] <dstfile>');
+ Writeln('Usage: concat [-i] <srcfile1> [<srcfile2> ..] <dstfile>');
+ Writeln;
+ Writeln('Options:');
+ Writeln(' -i Ignore non-existent files');
Writeln;
halt(1);
end;
@@ -22,11 +27,23 @@ procedure DoConcat;
Src: TextFile;
I: Longint;
Line: Ansistring;
+ OldFilemode: byte;
begin
- for I:=1 to ParamCount-1 do
+ OldFilemode:=FileMode;
+ Filemode:=0;
+ for I:=0 to FileList.Count-1 do
begin
- Assign(Src,ParamStr(I));
+ Assign(Src,FileList[i]);
+ {$i-}
Reset(Src);
+ while ioresult<>0 do
+ begin
+ { wait for lingering locks to disappear }
+ Sleep(200);
+ Reset(Src);
+ end;
+ {$i+}
+
while not Eof(Src) do
begin
ReadLn(Src,Line);
@@ -34,17 +51,28 @@ procedure DoConcat;
end;
Close(Src);
end;
+ Filemode:=OldFilemode;
Close(Dst);
end;
procedure CheckParas;
var
+ FirstFile,
I: Longint;
+ Exists: boolean;
begin
{ enough parameters? }
if ParamCount<2 then
Usage;
+
+ FirstFile:=1;
+ if UpperCase(ParamStr(1))='-i' then
+ begin
+ IgnoreNonExisting:=true;
+ Inc(FirstFile);
+ end;
+
{ check destination }
if DirectoryExists(ParamStr(ParamCount)) then
begin
@@ -61,23 +89,32 @@ procedure CheckParas;
halt(2);
end;
{ check source(s) }
- for I:=1 to ParamCount-1 do
+ for I:=FirstFile to ParamCount-1 do
begin
+ Exists:=True;
if not FileExists(ParamStr(I)) then
begin
- Writeln('File "',ParamStr(I),'" does not exist');
- halt(2);
- end;
- if DirectoryExists(ParamStr(I)) then
+ if not IgnoreNonExisting then
+ begin
+ Writeln('File "',ParamStr(I),'" does not exist');
+ halt(2);
+ end;
+ Exists:=False;
+ end
+ else if DirectoryExists(ParamStr(I)) then
begin
Writeln('"',ParamStr(I),'" is a directory');
halt(2);
- end;
- end;
+ end
+ else if Exists then
+ FileList.Add(ParamStr(I));
+ end
end;
begin
+ FileList:=TStringList.Create;
CheckParas;
DoConcat;
+ FileList.Free;
end.
diff --git a/tests/utils/dotest.pp b/tests/utils/dotest.pp
index 79abec5961..1c69abd6cd 100644
--- a/tests/utils/dotest.pp
+++ b/tests/utils/dotest.pp
@@ -431,6 +431,26 @@ begin
end;
+procedure ForceLog(const logfile:string);
+var
+ t : text;
+begin
+ assign(t,logfile);
+ {$I-}
+ append(t);
+ {$I+}
+ if ioresult<>0 then
+ begin
+ {$I-}
+ rewrite(t);
+ {$I+}
+ if ioresult<>0 then
+ Verbose(V_Abort,'Can''t Create '+logfile);
+ end;
+ close(t);
+end;
+
+
function GetCompilerInfo(c:tcompinfo):boolean;
function GetToken(var s:string):string;
@@ -697,6 +717,23 @@ begin
end;
+function TestLogFileName(Const pref,base,ext:String):String;
+var
+ LogDir: String;
+begin
+ LogDir:=TestOutputDir;
+{$ifndef macos}
+ if UniqueSuffix<>'' then
+ LogDir:=LogDir+'/..';
+ TestLogFileName:=LogDir+'/'+ForceExtension(pref+SplitFileName(base),ext);
+{$else macos}
+ if UniqueSuffix<>'' then
+ LogDir:=LogDir+'::';
+ TestLogFileName:=ConcatMacPath(LogDir,ForceExtension(pref+SplitFileName(base),ext));
+{$endif macos}
+end;
+
+
function ExitWithInternalError(const OutName:string):boolean;
var
t : text;
@@ -855,6 +892,9 @@ var
begin
RunCompiler:=false;
args:='-n -T'+CompilerTarget+' -Fu'+RTLUnitsDir;
+ { the helper object files have been copied to the common directory }
+ if UniqueSuffix<>'' then
+ args:=args+' -Fo'+TestOutputDir+'/..';
args:=args+' -FE'+TestOutputDir;
if TargetIsMacOS then
args:=args+' -WT '; {tests should be compiled as MPWTool}
@@ -1092,6 +1132,7 @@ begin
end;
LibraryExists:=false;
end;
+
function ExecuteRemote(const prog,args:string;out StartTicks,EndTicks : int64):boolean;
const
MaxTrials = 5;
@@ -1134,18 +1175,60 @@ end;
function MaybeCopyFiles(const FileToCopy : string) : boolean;
var
TestRemoteExe,
- s : string;
pref : string;
LocalFile, RemoteFile: string;
LocalPath: string;
- index : integer;
+ i : integer;
execres : boolean;
EndTicks,
StartTicks : int64;
+ FileList : TStringList;
+
+ function BuildFileList: TStringList;
+ var
+ s : string;
+ index : longint;
+ begin
+ s:=Config.Files;
+ if length(s) = 0 then
+ begin
+ Result:=nil;
+ exit;
+ end;
+ Result:=TStringList.Create;
+ repeat
+ index:=pos(' ',s);
+ if index=0 then
+ LocalFile:=s
+ else
+ LocalFile:=copy(s,1,index-1);
+ Result.Add(LocalFile);
+ if index=0 then
+ break;
+ s:=copy(s,index+1,length(s)-index);
+ until false;
+ end;
+
begin
if RemoteAddr='' then
begin
- exit(false);
+ If UniqueSuffix<>'' then
+ begin
+ FileList:=BuildFileList;
+ if assigned(FileList) then
+ begin
+ LocalPath:=SplitPath(PPFile[current]);
+ if Length(LocalPath) > 0 then
+ LocalPath:=LocalPath+'/';
+ for i:=0 to FileList.count-1 do
+ begin
+ LocalFile:=FileList[i];
+ CopyFile(LocalPath+LocalFile,TestOutputDir+'/'+LocalFile,false);
+ end;
+ FileList.Free;
+ end;
+ end;
+ exit(true);
end;
execres:=true;
{ We don't want to create subdirs, remove paths from the test }
@@ -1160,36 +1243,32 @@ begin
Verbose(V_normal, 'Could not copy executable '+FileToCopy);
exit(execres);
end;
- s:=Config.Files;
- if length(s) > 0 then
+ FileList:=BuildFileList;
+ if assigned(FileList) then
begin
LocalPath:=SplitPath(PPFile[current]);
if Length(LocalPath) > 0 then
LocalPath:=LocalPath+'/';
- repeat
- index:=pos(' ',s);
- if index=0 then
- LocalFile:=s
- else
- LocalFile:=copy(s,1,index-1);
- RemoteFile:=RemotePath+'/'+SplitFileName(LocalFile);
- LocalFile:=LocalPath+LocalFile;
- if DoVerbose and (rcpprog='pscp') then
- pref:='-v '
- else
- pref:='';
- execres:=ExecuteRemote(rcpprog,pref+RemotePara+' '+LocalFile+' '+
- RemoteAddr+':'+RemoteFile,StartTicks,EndTicks);
- if not execres then
+ for i:=0 to FileList.count-1 do
begin
- Verbose(V_normal, 'Could not copy required file '+LocalFile);
- exit(false);
+ LocalFile:=FileList[i];
+ RemoteFile:=RemotePath+'/'+SplitFileName(LocalFile);
+ LocalFile:=LocalPath+LocalFile;
+ if DoVerbose and (rcpprog='pscp') then
+ pref:='-v '
+ else
+ pref:='';
+ execres:=ExecuteRemote(rcpprog,pref+RemotePara+' '+LocalFile+' '+
+ RemoteAddr+':'+RemoteFile,StartTicks,EndTicks);
+ if not execres then
+ begin
+ Verbose(V_normal, 'Could not copy required file '+LocalFile);
+ FileList.Free;
+ exit(false);
+ end;
end;
- if index=0 then
- break;
- s:=copy(s,index+1,length(s)-index);
- until false;
end;
+ FileList.Free;
MaybeCopyFiles:=execres;
end;
@@ -1213,8 +1292,9 @@ begin
RunExecutable:=false;
execres:=true;
- TestExe:=OutputFileName(PPFile[current],ExeExt);
+ TestExe:=TestOutputFilename('',PPFile[current],ExeExt);
+ execres:=MaybeCopyFiles(TestExe);
if EmulatorName<>'' then
begin
{ Get full name out log file, because we change the directory during
@@ -1233,7 +1313,6 @@ begin
end
else if RemoteAddr<>'' then
begin
- execres:=MaybeCopyFiles(TestExe);
TestRemoteExe:=RemotePath+'/'+SplitFileName(TestExe);
{ rsh doesn't pass the exitcode, use a second command to print the exitcode
on the remoteshell to stdout }
@@ -1609,9 +1688,9 @@ begin
Res:=GetCompilerCPU;
Res:=GetCompilerTarget;
{$ifndef MACOS}
- RTLUnitsDir:='units/'+CompilerFullTarget;
+ RTLUnitsDir:='tstunits/'+CompilerFullTarget;
{$else MACOS}
- RTLUnitsDir:=':units:'+CompilerFullTarget;
+ RTLUnitsDir:=':tstunits:'+CompilerFullTarget;
{$endif MACOS}
if not PathExists(RTLUnitsDir) then
Verbose(V_Abort,'Unit path "'+RTLUnitsDir+'" does not exists');
@@ -1630,22 +1709,30 @@ begin
begin
{$ifndef MACOS}
TestOutputDir:=OutputDir+'/'+PPDir;
+ if UniqueSuffix<>'' then
+ TestOutputDir:=TestOutputDir+'/'+UniqueSuffix;
{$else MACOS}
TestOutputDir:=OutputDir+PPDir;
+ if UniqueSuffix<>'' then
+ TestOutputDir:=TestOutputDir+':'+UniqueSuffix;
{$endif MACOS}
mkdirtree(TestOutputDir);
end
else
TestOutputDir:=OutputDir;
- { Global log files (don't use UniqueSuffix here, it's not set in case of
- SINGLEDOTESTRUNS) }
- LogSuffix:=SplitBasePath(PPDir)+'log';
+ if UniqueSuffix<>'' then
+ LogSuffix:=UniqueSuffix
+ else
+ LogSuffix:=SplitBasePath(PPDir)+'log';
ResLogFile:=OutputFileName('log',LogSuffix);
LongLogFile:=OutputFileName('longlog',LogSuffix);
FailLogFile:=OutputFileName('faillist',LogSuffix);
+ ForceLog(ResLogFile);
+ ForceLog(LongLogFile);
+ ForceLog(FailLogFile);
{ Per test logfiles }
- CompilerLogFile:=TestOutputFileName('',SplitFileName(PPFile[current]),'log');
- ExeLogFile:=TestOutputFileName('',SplitFileName(PPFile[current]),'elg');
+ CompilerLogFile:=TestLogFileName('',SplitFileName(PPFile[current]),'log');
+ ExeLogFile:=TestLogFileName('',SplitFileName(PPFile[current]),'elg');
Verbose(V_Debug,'Using Compiler logfile: '+CompilerLogFile);
Verbose(V_Debug,'Using Execution logfile: '+ExeLogFile);
end;
diff --git a/tests/utils/gparmake.pp b/tests/utils/gparmake.pp
new file mode 100644
index 0000000000..ada3801aa9
--- /dev/null
+++ b/tests/utils/gparmake.pp
@@ -0,0 +1,166 @@
+{ See procedure "Usage". This code is in the public domain. }
+
+Program GParMake;
+
+procedure Usage;
+ begin
+ writeln('GParMake: create make rules for parallel execution of testsuite');
+ writeln('Usage: gparmake [-a] <outputfile> <startchunk> <tests_per_chunk> <test1> [<test2> ...]');
+ writeln('Output: makefile fragment with rules to run the tests in sequences of <tests_per_chunk>');
+ writeln;
+ halt(1);
+ end;
+
+{ make all numbers of the same string length so they can be sorted
+ lexographically }
+function rulenr2str(rulenr: longint): string;
+ var
+ i: longint;
+ begin
+ str(rulenr:9,rulenr2str);
+ for i:=1 to length(rulenr2str)-1 do
+ if rulenr2str[i]=' ' then
+ rulenr2str[i]:='0';
+ end;
+
+procedure WriteChunkRule(rulenr: longint; const files: ansistring);
+ var
+ rulestr: string;
+ begin
+ rulestr:=rulenr2str(rulenr);
+ writeln('$(TEST_OUTPUTDIR)/testchunk_',rulestr,'-stamp.$(TEST_FULL_TARGET): testprep-stamp.$(TEST_FULL_TARGET)');
+ writeln(#9'$(Q)$(DOTEST) $(DOTESTOPT) -Lchunk',rulestr,' -e ',files);
+ writeln(#9'$(ECHOREDIR) $(DATE) > $@');
+ writeln;
+ writeln('$(addsuffix .chunk',rulestr,', $(LOGFILES)) : $(TEST_OUTPUTDIR)/testchunk_',rulestr,'-stamp.$(TEST_FULL_TARGET)');
+ writeln;
+ writeln('.INTERMEDIATE: $(addsuffix .chunk',rulestr,', $(LOGFILES)) $(TEST_OUTPUTDIR)/testchunk_',rulestr,'-stamp.$(TEST_FULL_TARGET)');
+ writeln;
+ end;
+
+
+var
+ startchunk: longint;
+ doappend: boolean;
+
+Function ProcessArgs: longint;
+ var
+ i,
+ paramnr,
+ chunktargetsize,
+ chunksize,
+ chunknr,
+ error: longint;
+ testname,
+ nexttestname,
+ testlist,
+ outputname: ansistring;
+
+ procedure FlushChunk;
+ begin
+ WriteChunkRule(chunknr,testlist);
+ inc(chunknr);
+ testlist:='';
+ chunksize:=0;
+ end;
+
+ begin
+ if paramcount < 3 then
+ Usage;
+
+ doappend:=false;
+
+ paramnr:=1;
+ if paramstr(paramnr)='-a' then
+ begin
+ doappend:=true;
+ inc(paramnr);
+ end;
+
+ outputname:=paramstr(paramnr);
+ inc(paramnr);
+
+ val(paramstr(paramnr),startchunk,error);
+ if error<>0 then
+ Usage;
+ inc(paramnr);
+
+ val(paramstr(paramnr),chunktargetsize,error);
+ if error<>0 then
+ Usage;
+ inc(paramnr);
+
+ { only redirect output after all possible cases where we may have to write
+ the usage screen }
+ assign(output,outputname);
+ if doappend then
+ append(output)
+ else
+ rewrite(output);
+
+ chunknr:=startchunk;
+ chunksize:=0;
+ testlist:='';
+ for i := paramnr to paramcount do
+ begin
+ testname:=paramstr(i);
+ testlist:=testlist+' '+testname;
+ inc(chunksize);
+ if chunksize>=chunktargetsize then
+ begin
+ if (i=paramcount) then
+ FlushChunk
+ else
+ begin
+ { keep tests with the same name except for the last character in the same chunk,
+ because they may have to be executed in order (skip ".pp" suffix and last char) }
+ nexttestname:=paramstr(i+1);
+ if lowercase(copy(testname,1,length(testname)-4))<>lowercase(copy(nexttestname,1,length(nexttestname)-4)) then
+ FlushChunk;
+ end;
+ end;
+ end;
+ if chunksize<>0 then
+ FlushChunk;
+ ProcessArgs:=chunknr-1;
+ end;
+
+
+procedure WriteWrapperRules(totalchunks: longint);
+ const
+ lognames: array[1..3] of string[11] = ('log','faillist','longlog');
+ var
+ logi,
+ i: longint;
+ begin
+ for logi:=1 to 3 do
+ begin
+ write('$(TEST_OUTPUTDIR)/',lognames[logi],' :');
+ for i:=startchunk to totalchunks do
+ write(' $(TEST_OUTPUTDIR)/',lognames[logi],'.chunk',rulenr2str(i));
+ writeln;
+ { if you have multiple rules for one (non-pattern) target, all
+ prerequisites will be merged, but only one of the rules can have a
+ recipe }
+ if not doappend then
+ begin
+ writeln(#9'$(Q)$(CONCAT) $(sort $^) $@');
+ writeln;
+ end;
+ writeln;
+ end;
+ if not doappend then
+ begin
+ writeln('allexectests : $(LOGFILES)');
+ writeln;
+ end;
+ end;
+
+
+var
+ totalchunks: longint;
+begin
+ totalchunks:=ProcessArgs;
+ WriteWrapperRules(totalchunks);
+ close(output);
+end.