Browse Source

* compiler dependent utils in utils/ subdir

peter 24 năm trước cách đây
mục cha
commit
76e6770898

+ 73 - 34
compiler/Makefile

@@ -1,13 +1,13 @@
 #
-# Don't edit, this file is generated by fpcmake v1.99.0 [2001/02/24]
+# Don't edit, this file is generated by fpcmake v1.99.0 [2001/04/25]
 #
 default: all
 override PATH:=$(subst \,/,$(PATH))
 ifeq ($(findstring ;,$(PATH)),)
 inUnix=1
-SEARCHPATH=$(subst :, ,$(PATH))
+SEARCHPATH:=$(subst :, ,$(PATH))
 else
-SEARCHPATH=$(subst ;, ,$(PATH))
+SEARCHPATH:=$(subst ;, ,$(PATH))
 endif
 PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
 ifeq ($(PWD),)
@@ -50,7 +50,7 @@ endif
 ifdef inUnix
 PATHSEP=/
 else
-PATHSEP=$(subst /,\,/)
+PATHSEP:=$(subst /,\,/)
 endif
 ifdef PWD
 BASEDIR:=$(shell $(PWD))
@@ -115,8 +115,8 @@ endif
 endif
 endif
 endif
-UNITSDIR=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
-PACKAGESDIR=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
 override PACKAGE_NAME=fpcompiler
 override PACKAGE_VERSION=1.1
 unexport OS_SOURCE FPC_VERSION
@@ -176,6 +176,7 @@ override LOCALDEF+=-dSUPPORT_MMX
 endif
 override LOCALOPT+=$(LOCALDEF)
 override FPCOPT:=$(LOCALOPT)
+override TARGET_DIRS+=utils
 override COMPILER_INCLUDEDIR+=$(CPU_TARGET)
 override COMPILER_UNITDIR+=$(CPU_TARGET) targets
 override COMPILER_TARGETDIR+=.
@@ -235,6 +236,9 @@ endif
 ifndef LD
 LD=ld
 endif
+ifndef RC
+RC=rc
+endif
 PPAS=ppas$(BATCHEXT)
 ifdef inUnix
 LDCONFIG=ldconfig
@@ -603,6 +607,9 @@ ifdef CFGFILE
 override FPCOPT+=@$(CFGFILE)
 endif
 ifeq ($(OS_SOURCE),win32)
+USEENV=1
+endif
+ifdef USEENV
 override FPCEXTCMD:=$(FPCOPT)
 override FPCOPT:=!FPCEXTCMD
 export FPCEXTCMD
@@ -687,14 +694,13 @@ fpc_sourceinstall: distclean
 	$(MKDIR) $(INSTALL_SOURCEDIR)
 	$(COPYTREE) $(BASEDIR) $(INSTALL_SOURCEDIR)
 fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
-ifdef EXAMPLESOURCEFILES
+ifdef HASEXAMPLES
 	$(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
 	$(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
 endif
 ifdef TARGET_EXAMPLEDIRS
-ifndef EXAMPLESOURCEFILES
-	$(MKDIR) $(INSTALL_EXAMPLEDIR)
-endif
 	$(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
 endif
 fpc_distinstall: fpc_install fpc_exampleinstall
@@ -764,7 +770,9 @@ endif
 fpc_zipsourceinstall:
 	$(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=src
 fpc_zipexampleinstall:
+ifdef HASEXAMPLES
 	$(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=exm
+endif
 fpc_zipdistinstall:
 	$(MAKE) fpc_zipinstall ZIPTARGET=distinstall
 .PHONY: fpc_clean fpc_cleanall fpc_distclean
@@ -885,6 +893,46 @@ fpc_info:
 	@$(ECHO)  DIST_DESTDIR......... $(DIST_DESTDIR)
 	@$(ECHO)  DIST_ZIPNAME......... $(DIST_ZIPNAME)
 	@$(ECHO)
+TARGET_DIRS_UTILS=1
+ifdef TARGET_DIRS_UTILS
+utils_all:
+	$(MAKE) -C utils all
+utils_debug:
+	$(MAKE) -C utils debug
+utils_examples:
+	$(MAKE) -C utils examples
+utils_smart:
+	$(MAKE) -C utils smart
+utils_shared:
+	$(MAKE) -C utils shared
+utils_install:
+	$(MAKE) -C utils install
+utils_sourceinstall:
+	$(MAKE) -C utils sourceinstall
+utils_exampleinstall:
+	$(MAKE) -C utils exampleinstall
+utils_distinstall:
+	$(MAKE) -C utils distinstall
+utils_zipinstall:
+	$(MAKE) -C utils zipinstall
+utils_zipsourceinstall:
+	$(MAKE) -C utils zipsourceinstall
+utils_zipexampleinstall:
+	$(MAKE) -C utils zipexampleinstall
+utils_zipdistinstall:
+	$(MAKE) -C utils zipdistinstall
+utils_clean:
+	$(MAKE) -C utils clean
+utils_distclean:
+	$(MAKE) -C utils distclean
+utils_cleanall:
+	$(MAKE) -C utils cleanall
+utils_info:
+	$(MAKE) -C utils info
+utils:
+	$(MAKE) -C utils all
+.PHONY: utils_all utils_debug utils_examples utils_smart utils_shared utils_install utils_sourceinstall utils_exampleinstall utils_distinstall utils_zipinstall utils_zipsourceinstall utils_zipexampleinstall utils_zipdistinstall utils_clean utils_distclean utils_cleanall utils_info utils
+endif
 ifndef DIFF
 DIFF:=$(strip $(wildcard $(addsuffix /diff$(SRCEXEEXT),$(SEARCHPATH))))
 ifeq ($(DIFF),)
@@ -903,19 +951,19 @@ CMP:=$(firstword $(CMP))
 endif
 endif
 export CMP
-debug: fpc_debug
-examples: fpc_examples
-smart: fpc_smart
-shared: fpc_shared
+debug: fpc_debug $(addsuffix _debug,$(TARGET_DIRS))
+examples: fpc_examples $(addsuffix _examples,$(TARGET_DIRS))
+smart: fpc_smart $(addsuffix _smart,$(TARGET_DIRS))
+shared: fpc_shared $(addsuffix _shared,$(TARGET_DIRS))
 sourceinstall: fpc_sourceinstall
-exampleinstall: fpc_exampleinstall
-distinstall: fpc_distinstall
+exampleinstall: fpc_exampleinstall $(addsuffix _exampleinstall,$(TARGET_DIRS))
+distinstall: fpc_distinstall $(addsuffix _distinstall,$(TARGET_DIRS))
 zipinstall: fpc_zipinstall
 zipsourceinstall: fpc_zipsourceinstall
-zipexampleinstall: fpc_zipexampleinstall
-zipdistinstall: fpc_zipdistinstall
-cleanall: fpc_cleanall
-info: fpc_info
+zipexampleinstall: fpc_zipexampleinstall $(addsuffix _zipexampleinstall,$(TARGET_DIRS))
+zipdistinstall: fpc_zipdistinstall $(addsuffix _zipdistinstall,$(TARGET_DIRS))
+cleanall: fpc_cleanall $(addsuffix _cleanall,$(TARGET_DIRS))
+info: fpc_info $(addsuffix _info,$(TARGET_DIRS))
 .PHONY: debug examples smart shared sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall cleanall info
 ifneq ($(wildcard fpcmake.loc),)
 include fpcmake.loc
@@ -935,7 +983,6 @@ endif
 else
 DIFFRESULT=No diff program
 endif
-FPCEXE=fpc$(EXEEXT)
 PPEXENAME=pp$(EXEEXT)
 EXENAME=ppc$(CPUSUF)$(EXEEXT)
 TEMPNAME=ppc$(EXEEXT)
@@ -952,8 +999,7 @@ m68k:
 	$(MAKE) M68K=1 all
 powerpc:
 	$(MAKE) POWERPC=1 all
-all: $(EXENAME)
-fpcexe: $(FPCEXE)
+all: $(EXENAME) $(addsuffix _all,$(TARGET_DIRS))
 ifeq ($(MAKELEVEL),0)
 ifndef STARTTIME
 ifdef DATE
@@ -984,12 +1030,12 @@ next :
 	$(MAKE) $(EXENAME)
 	$(MAKE) echotime
 endif
-clean : execlean fpc_cleanall
 ppuclean:
 	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
 execlean :
 	-$(DEL) fpc$(EXEEXT) ppc386$(EXEEXT) ppcaxp$(EXEEXT) ppc68k$(EXEEXT) ppcppc$(EXEEXT)
-distclean: clean
+clean : execlean fpc_cleanall $(addsuffix _clean,$(TARGET_DIRS))
+distclean: execlean fpc_cleanall $(addsuffix _distclean,$(TARGET_DIRS))
 	-$(DEL) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC)
 $(MAKEDEP): $(UTILSDIR)/ppdep.pp
 	$(COMPILER) $(UTILSDIR)/ppdep.pp
@@ -1048,6 +1094,7 @@ cycle:
 	$(MAKE) -C $(UNITDIR_RTL) clean
 	$(MAKE) -C $(UNITDIR_RTL) 'OPT=$(RTLOPTS)' all
 	$(MAKE) remake3
+	$(MAKE) $(addsuffix _all,$(TARGET_DIRS))
 	$(MAKE) echotime
 cycledep:
 	$(MAKE) cycle USEDEPEND=1
@@ -1055,16 +1102,8 @@ cvstest:
 	$(MAKE) cycle 'LOCALOPT=-n -Se' 'RTLOPTS=-n -Se'
 .PHONY: quickinstall install installsym
 MSGINSTALLDIR=$(INSTALL_BASEDIR)/msg
-override FPCEXEFILE:=$(wildcard $(FPCEXE))
 override PPEXEFILE:=$(wildcard $(EXENAME))
-quickinstall:
-ifneq ($(FPCEXEFILE),)
-ifdef UPXPROG
-	-$(UPXPROG) $(FPCEXEFILE)
-endif
-	$(MKDIR) $(INSTALL_BINDIR)
-	$(INSTALLEXE) $(FPCEXEFILE) $(INSTALL_BINDIR)
-endif
+quickinstall: $(addsuffix _install,$(TARGET_DIRS))
 ifneq ($(PPEXEFILE),)
 ifdef UPXPROG
 	-$(UPXPROG) $(EXENAME)

+ 10 - 18
compiler/Makefile.fpc

@@ -6,6 +6,9 @@
 name=fpcompiler
 version=1.1
 
+[target]
+dirs=utils
+
 [compiler]
 targetdir=.
 unitdir=$(CPU_TARGET) targets
@@ -139,7 +142,6 @@ endif
 # Setup os-independent filenames
 #####################################################################
 
-FPCEXE=fpc$(EXEEXT)
 PPEXENAME=pp$(EXEEXT)
 EXENAME=ppc$(CPUSUF)$(EXEEXT)
 TEMPNAME=ppc$(EXEEXT)
@@ -171,9 +173,7 @@ powerpc:
 # Default makefile
 #####################################################################
 
-all: $(EXENAME)
-
-fpcexe: $(FPCEXE)
+all: $(EXENAME) $(addsuffix _all,$(TARGET_DIRS))
 
 ifeq ($(MAKELEVEL),0)
 ifndef STARTTIME
@@ -210,15 +210,15 @@ next :
         $(MAKE) echotime
 endif
 
-clean : execlean fpc_cleanall
-
 ppuclean:
         -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
 
 execlean :
         -$(DEL) fpc$(EXEEXT) ppc386$(EXEEXT) ppcaxp$(EXEEXT) ppc68k$(EXEEXT) ppcppc$(EXEEXT)
 
-distclean: clean
+clean : execlean fpc_cleanall $(addsuffix _clean,$(TARGET_DIRS))
+
+distclean: execlean fpc_cleanall $(addsuffix _distclean,$(TARGET_DIRS))
         -$(DEL) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC)
 
 
@@ -307,6 +307,7 @@ cycle:
         $(MAKE) -C $(UNITDIR_RTL) clean
         $(MAKE) -C $(UNITDIR_RTL) 'OPT=$(RTLOPTS)' all
         $(MAKE) remake3
+        $(MAKE) $(addsuffix _all,$(TARGET_DIRS))
         $(MAKE) echotime
 
 cycledep:
@@ -323,19 +324,10 @@ cvstest:
 .PHONY: quickinstall install installsym
 
 MSGINSTALLDIR=$(INSTALL_BASEDIR)/msg
-override FPCEXEFILE:=$(wildcard $(FPCEXE))
 override PPEXEFILE:=$(wildcard $(EXENAME))
 
 # This will only install the ppc386.exe, not the message files etc.
-quickinstall:
-# Install fpc.exe
-ifneq ($(FPCEXEFILE),)
-ifdef UPXPROG
-        -$(UPXPROG) $(FPCEXEFILE)
-endif
-        $(MKDIR) $(INSTALL_BINDIR)
-        $(INSTALLEXE) $(FPCEXEFILE) $(INSTALL_BINDIR)
-endif
+quickinstall: $(addsuffix _install,$(TARGET_DIRS))
 # Install ppc386.exe
 ifneq ($(PPEXEFILE),)
 ifdef UPXPROG
@@ -391,4 +383,4 @@ localmake:=$(strip $(wildcard makefile.loc))
 
 ifdef localmake
 include ./$(localmake)
-endif
+endif

+ 17 - 10
compiler/new/Makefile

@@ -1,13 +1,13 @@
 #
-# Don't edit, this file is generated by fpcmake v1.99.0 [2001/02/24]
+# Don't edit, this file is generated by fpcmake v1.99.0 [2001/04/25]
 #
 default: all
 override PATH:=$(subst \,/,$(PATH))
 ifeq ($(findstring ;,$(PATH)),)
 inUnix=1
-SEARCHPATH=$(subst :, ,$(PATH))
+SEARCHPATH:=$(subst :, ,$(PATH))
 else
-SEARCHPATH=$(subst ;, ,$(PATH))
+SEARCHPATH:=$(subst ;, ,$(PATH))
 endif
 PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
 ifeq ($(PWD),)
@@ -50,7 +50,7 @@ endif
 ifdef inUnix
 PATHSEP=/
 else
-PATHSEP=$(subst /,\,/)
+PATHSEP:=$(subst /,\,/)
 endif
 ifdef PWD
 BASEDIR:=$(shell $(PWD))
@@ -107,8 +107,8 @@ endif
 endif
 endif
 endif
-UNITSDIR=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
-PACKAGESDIR=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
 override PACKAGE_NAME=fpcompiler
 override PACKAGE_VERSION=1.1
 unexport OS_SOURCE FPC_VERSION
@@ -228,6 +228,9 @@ endif
 ifndef LD
 LD=ld
 endif
+ifndef RC
+RC=rc
+endif
 PPAS=ppas$(BATCHEXT)
 ifdef inUnix
 LDCONFIG=ldconfig
@@ -596,6 +599,9 @@ ifdef CFGFILE
 override FPCOPT+=@$(CFGFILE)
 endif
 ifeq ($(OS_SOURCE),win32)
+USEENV=1
+endif
+ifdef USEENV
 override FPCEXTCMD:=$(FPCOPT)
 override FPCOPT:=!FPCEXTCMD
 export FPCEXTCMD
@@ -680,14 +686,13 @@ fpc_sourceinstall: distclean
 	$(MKDIR) $(INSTALL_SOURCEDIR)
 	$(COPYTREE) $(BASEDIR) $(INSTALL_SOURCEDIR)
 fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
-ifdef EXAMPLESOURCEFILES
+ifdef HASEXAMPLES
 	$(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
 	$(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
 endif
 ifdef TARGET_EXAMPLEDIRS
-ifndef EXAMPLESOURCEFILES
-	$(MKDIR) $(INSTALL_EXAMPLEDIR)
-endif
 	$(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
 endif
 fpc_distinstall: fpc_install fpc_exampleinstall
@@ -757,7 +762,9 @@ endif
 fpc_zipsourceinstall:
 	$(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=src
 fpc_zipexampleinstall:
+ifdef HASEXAMPLES
 	$(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=exm
+endif
 fpc_zipdistinstall:
 	$(MAKE) fpc_zipinstall ZIPTARGET=distinstall
 .PHONY: fpc_clean fpc_cleanall fpc_distclean

+ 804 - 0
compiler/utils/Makefile

@@ -0,0 +1,804 @@
+#
+# Don't edit, this file is generated by fpcmake v1.99.0 [2001/04/25]
+#
+default: all
+override PATH:=$(subst \,/,$(PATH))
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(subst :, ,$(PATH))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+nopwd:
+	@echo You need the GNU utils package to use this Makefile!
+	@echo Get ftp://ftp.freepascal.org/pub/fpc/dist/go32v2/utilgo32.zip
+	@exit
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygwin,$(MACH_TYPE)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+BATCHEXT=.sh
+else
+ifdef inOS2
+BATCHEXT=.cmd
+else
+BATCHEXT=.bat
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+endif
+ifdef PWD
+BASEDIR:=$(shell $(PWD))
+else
+BASEDIR=.
+endif
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+else
+FPC=ppc386
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+ifndef OS_TARGET
+OS_TARGET:=$(shell $(FPC) -iTO)
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(shell $(FPC) -iSO)
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(shell $(FPC) -iTP)
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(shell $(FPC) -iSP)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(shell $(FPC) -iV)
+endif
+export FPC OS_TARGET OS_SOURCE CPU_TARGET CPU_SOURCE FPC_VERSION
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifeq ($(FPCDIR),wrong)
+override FPCDIR=../..
+ifeq ($(wildcard $(FPCDIR)/rtl),)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove
+override CLEAN_UNITS+=ppu crc
+override COMPILER_UNITDIR+=..
+override COMPILER_SOURCEDIR+=..
+override COMPILER_TARGETDIR+=.
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(EXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+ifndef COPY
+COPY:=cp -fp
+endif
+ifndef COPYTREE
+COPYTREE:=cp -rfp
+endif
+ifndef MOVE
+MOVE:=mv -f
+endif
+ifndef DEL
+DEL:=rm -f
+endif
+ifndef DELTREE
+DELTREE:=rm -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=install -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=install -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+ifdef inUnix
+MKDIR:=install -m 755 -d
+else
+MKDIR:=ginstall -m 755 -d
+endif
+endif
+export ECHO COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef AS
+AS=as
+endif
+ifndef LD
+LD=ld
+endif
+ifndef RC
+RC=rc
+endif
+PPAS=ppas$(BATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE=
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef PPUFILES
+PPUFILES:=$(strip $(wildcard $(addsuffix /ppufiles$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUFILES),)
+PPUFILES=
+else
+PPUFILES:=$(firstword $(PPUFILES))
+endif
+endif
+export PPUFILES
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEACHPATH))))
+ifeq ($(DATE),)
+DATE=
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ifndef UPXPROG
+ifeq ($(OS_TARGET),go32v2)
+UPXPROG:=1
+endif
+ifeq ($(OS_TARGET),win32)
+UPXPROG:=1
+endif
+ifdef UPXPROG
+UPXPROG:=$(strip $(wildcard $(addsuffix /upx$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(UPXPROG),)
+UPXPROG=
+else
+UPXPROG:=$(firstword $(UPXPROG))
+endif
+else
+UPXPROG=
+endif
+endif
+export UPXPROG
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG=
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ZIPOPT=-9
+ZIPEXT=.zip
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG=
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ifeq ($(USETAR),bz2)
+TAROPT=vI
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+LIBPREFIX=lib
+RSTEXT=.rst
+FPCMADE=fpcmade
+ifeq ($(OS_TARGET),go32v1)
+PPUEXT=.pp1
+OEXT=.o1
+ASMEXT=.s1
+SMARTEXT=.sl1
+STATICLIBEXT=.a1
+SHAREDLIBEXT=.so1
+LIBPREFIX=
+FPCMADE=fpcmade.v1
+PACKAGESUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+LIBPREFIX=
+FPCMADE=fpcmade.dos
+ZIPSUFFIX=go32
+endif
+ifeq ($(OS_TARGET),linux)
+EXEEXT=
+HASSHAREDLIB=1
+FPCMADE=fpcmade.lnx
+ZIPSUFFIX=linux
+endif
+ifeq ($(OS_TARGET),freebsd)
+EXEEXT=
+HASSHAREDLIB=1
+FPCMADE=fpcmade.freebsd
+ZIPSUFFIX=freebsd
+endif
+ifeq ($(OS_TARGET),win32)
+PPUEXT=.ppw
+OEXT=.ow
+ASMEXT=.sw
+SMARTEXT=.slw
+STATICLIBEXT=.aw
+SHAREDLIBEXT=.dll
+FPCMADE=fpcmade.w32
+ZIPSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+PPUEXT=.ppo
+ASMEXT=.so2
+OEXT=.oo2
+AOUTEXT=.out
+SMARTEXT=.so
+STATICLIBEXT=.ao2
+SHAREDLIBEXT=.dll
+FPCMADE=fpcmade.os2
+ZIPSUFFIX=emx
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifeq ($(OS_TARGET),linux)
+UNIXINSTALLDIR=1
+endif
+ifeq ($(OS_TARGET),freebsd)
+UNIXINSTALLDIR=1
+endif
+else
+ifeq ($(OS_SOURCE),linux)
+UNIXINSTALLDIR=1
+endif
+ifeq ($(OS_SOURCE),freebsd)
+UNIXINSTALLDIR=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXINSTALLDIR
+INSTALL_PREFIX=/usr/local
+else
+INSTALL_PREFIX=/pp
+endif
+endif
+export INSTALL_PREFIX
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef INSTALL_BASEDIR
+ifdef UNIXINSTALLDIR
+INSTALL_BASEDIR=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXINSTALLDIR
+INSTALL_BINDIR=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR=$(INSTALL_BASEDIR)/bin/$(OS_TARGET)
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR=$(INSTALL_BASEDIR)/units/$(OS_TARGET)
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXINSTALLDIR
+INSTALL_LIBDIR=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXINSTALLDIR
+INSTALL_SOURCEDIR=$(INSTALL_PREFIX)/src/fpc-$(FPC_VERSION)
+else
+INSTALL_SOURCEDIR=$(INSTALL_BASEDIR)/source
+endif
+ifdef PACKAGE_NAME
+INSTALL_SOURCEDIR:=$(INSTALL_SOURCEDIR)/$(PACKAGE_NAME)
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXINSTALLDIR
+INSTALL_DOCDIR=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)
+else
+INSTALL_DOCDIR=$(INSTALL_BASEDIR)/doc
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXINSTALLDIR
+INSTALL_EXAMPLEDIR=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR=$(INSTALL_BASEDIR)/examples
+endif
+ifdef EXAMPLESUBDIR
+INSTALL_EXAMPLEDIR:=$(INSTALL_EXAMPLEDIR)/$(EXAMPLESUBDIR)
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifeq ($(OS_TARGET),linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(OS_TARGET),go32v2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(OS_TARGET),win32)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(OS_TARGET),os2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(OS_TARGET),freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR)))))
+ifneq ($(PACKAGEDIR_RTL),)
+PACKAGEDIR_RTL:=$(firstword $(PACKAGEDIR_RTL))
+ifeq ($(wildcard $(PACKAGEDIR_RTL)/$(FPCMADE)),)
+override COMPILEPACKAGES+=package_rtl
+package_rtl:
+	$(MAKE) -C $(PACKAGEDIR_RTL) all
+endif
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/$(OS_TARGET)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/$(OS_TARGET)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+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
+endif
+.PHONY: package_rtl
+override FPCOPTDEF=$(CPU_TARGET)
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+override FPCOPT+=-Xs -OG2p3 -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-OG2p3
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifeq ($(OS_SOURCE),win32)
+USEENV=1
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(OS_SOURCE),$(OS_TARGET))
+EXECPPAS:=@$(PPAS)
+endif
+endif
+.PHONY: fpc_exes
+ifdef TARGET_PROGRAMS
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(LIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+fpc_exes: $(EXEFILES)
+.PHONY: fpc_packages fpc_all fpc_smart fpc_debug
+$(FPCMADE): $(ALLTARGET)
+	@$(ECHO) Compiled > $(FPCMADE)
+fpc_packages: $(COMPILEPACKAGES)
+fpc_all: fpc_packages $(FPCMADE)
+fpc_smart:
+	$(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+	$(MAKE) all DEBUG=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .pp
+%$(PPUEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(PPUEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALLPPUFILES
+ifdef PPUFILES
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(INSTALLPPUFILES))
+override INSTALLPPULINKFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(shell $(PPUFILES) -S -O $(INSTALLPPUFILES)))
+else
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(LIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(INSTALLPPUFILES))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(INSTALLPPULINKFILES)))
+endif
+endif
+ifdef INSTALLEXEFILES
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(INSTALLEXEFILES))
+endif
+fpc_install: $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+	$(MKDIR) $(INSTALL_BINDIR)
+ifdef UPXPROG
+	-$(UPXPROG) $(INSTALLEXEFILES)
+endif
+	$(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+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
+fpc_distinstall: fpc_install fpc_exampleinstall
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+ifdef PPUFILES
+CLEANPPULINKFILES:=$(shell $(PPUFILES) $(CLEANPPUFILES))
+else
+CLEANPPULINKFILES:=$(wildcard $(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(LIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))))
+endif
+override CLEANPPULINKFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+	-$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+	-$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+	-$(DEL) $(FPCMADE) $(PPAS) link.res $(FPCEXTFILE) $(REDIRFILE)
+fpc_distclean: fpc_clean
+ifdef COMPILER_UNITTARGETDIR
+TARGETDIRCLEAN=fpc_clean
+endif
+fpc_cleanall: $(CLEANTARGET) $(TARGETDIRCLEAN)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+	-$(DELTREE) *$(SMARTEXT)
+	-$(DEL) $(FPCMADE) $(PPAS) link.res $(FPCEXTFILE) $(REDIRFILE)
+ifdef AOUTEXT
+	-$(DEL) *$(AOUTEXT)
+endif
+.PHONY: fpc_info
+fpc_info:
+	@$(ECHO)
+	@$(ECHO)  == Package info ==
+	@$(ECHO)  Package Name..... $(PACKAGE_NAME)
+	@$(ECHO)  Package Version.. $(PACKAGE_VERSION)
+	@$(ECHO)
+	@$(ECHO)  == Configuration info ==
+	@$(ECHO)
+	@$(ECHO)  FPC.......... $(FPC)
+	@$(ECHO)  FPC Version.. $(FPC_VERSION)
+	@$(ECHO)  Source CPU... $(CPU_SOURCE)
+	@$(ECHO)  Target CPU... $(CPU_TARGET)
+	@$(ECHO)  Source OS.... $(OS_SOURCE)
+	@$(ECHO)  Target OS.... $(OS_TARGET)
+	@$(ECHO)
+	@$(ECHO)  == Directory info ==
+	@$(ECHO)
+	@$(ECHO)  Basedir......... $(BASEDIR)
+	@$(ECHO)  FPCDir.......... $(FPCDIR)
+	@$(ECHO)  UnitsDir........ $(UNITSDIR)
+	@$(ECHO)  PackagesDir..... $(PACKAGESDIR)
+	@$(ECHO)
+	@$(ECHO)  GCC library..... $(GCCLIBDIR)
+	@$(ECHO)  Other library... $(OTHERLIBDIR)
+	@$(ECHO)
+	@$(ECHO)  == Tools info ==
+	@$(ECHO)
+	@$(ECHO)  Pwd....... $(PWD)
+	@$(ECHO)  Echo...... $(ECHO)
+	@$(ECHO)  PPUMove... $(PPUMOVE)
+	@$(ECHO)  PPUFiles.. $(PPUFILES)
+	@$(ECHO)  Date...... $(DATE)
+	@$(ECHO)  Upx....... $(UPXPROG)
+	@$(ECHO)  Zip....... $(ZIPPROG)
+	@$(ECHO)
+	@$(ECHO)  == Object info ==
+	@$(ECHO)
+	@$(ECHO)  Target Loaders...... $(TARGET_LOADERS)
+	@$(ECHO)  Target Units........ $(TARGET_UNITS)
+	@$(ECHO)  Target Programs..... $(TARGET_PROGRAMS)
+	@$(ECHO)  Target Dirs......... $(TARGET_DIRS)
+	@$(ECHO)  Target Examples..... $(TARGET_EXAMPLES)
+	@$(ECHO)  Target ExampleDirs.. $(TARGET_EXAMPLEDIRS)
+	@$(ECHO)
+	@$(ECHO)  Clean Units......... $(CLEAN_UNITS)
+	@$(ECHO)  Clean Files......... $(CLEAN_FILES)
+	@$(ECHO)
+	@$(ECHO)  Install Units....... $(INSTALL_UNITS)
+	@$(ECHO)  Install Files....... $(INSTALL_FILES)
+	@$(ECHO)
+	@$(ECHO)  == Install info ==
+	@$(ECHO)
+	@$(ECHO)  DateStr.............. $(DATESTR)
+	@$(ECHO)  ZipPrefix............ $(ZIPPREFIX)
+	@$(ECHO)  ZipSuffix............ $(ZIPSUFFIX)
+	@$(ECHO)
+	@$(ECHO)  INSTALL_BASEDIR...... $(INSTALL_BASEDIR)
+	@$(ECHO)  INSTALL_BINDIR....... $(INSTALL_BINDIR)
+	@$(ECHO)  INSTALL_LIBDIR....... $(INSTALL_LIBDIR)
+	@$(ECHO)  INSTALL_UNITDIR...... $(INSTALL_UNITDIR)
+	@$(ECHO)  INSTALL_SOURCEDIR.... $(INSTALL_SOURCEDIR)
+	@$(ECHO)  INSTALL_DOCDIR....... $(INSTALL_DOCDIR)
+	@$(ECHO)  INSTALL_DATADIR...... $(INSTALL_DATADIR)
+	@$(ECHO)
+	@$(ECHO)  DIST_DESTDIR......... $(DIST_DESTDIR)
+	@$(ECHO)  DIST_ZIPNAME......... $(DIST_ZIPNAME)
+	@$(ECHO)
+all: fpc_all
+debug: fpc_debug
+examples: fpc_examples
+smart: fpc_smart
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall: fpc_distinstall
+zipinstall:
+zipsourceinstall:
+zipexampleinstall:
+zipdistinstall:
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+.PHONY: all debug examples smart shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+ppu$(PPUEXT): ppu.pas
+ppufiles$(EXEEXT): ppufiles.pp ppu$(PPUEXT)
+ppudump$(EXEEXT): ppudump.pp ppu$(PPUEXT)
+ppumove$(EXEEXT): ppumove.pp ppu$(PPUEXT)
+unexport PPUFILES PPUMOVE

+ 37 - 0
compiler/utils/Makefile.fpc

@@ -0,0 +1,37 @@
+#
+#   Makefile.fpc for Free Pascal Compiler Utils
+#
+
+[target]
+programs=fpc ppufiles ppudump ppumove
+
+[clean]
+units=ppu crc
+
+[compiler]
+targetdir=.
+unitdir=..
+sourcedir=..
+
+[default]
+fpcdir=../..
+
+
+[rules]
+#
+# PPU Tools
+#
+ppu$(PPUEXT): ppu.pas
+
+ppufiles$(EXEEXT): ppufiles.pp ppu$(PPUEXT)
+
+ppudump$(EXEEXT): ppudump.pp ppu$(PPUEXT)
+
+ppumove$(EXEEXT): ppumove.pp ppu$(PPUEXT)
+
+#
+# Don't export some tools, which are found in the current dir if it's in
+# the path, so are not valid for the subdirs
+#
+
+unexport PPUFILES PPUMOVE

+ 4 - 0
compiler/fpc.pas → compiler/utils/fpc.pp

@@ -123,4 +123,8 @@ program fpc;
      halt(dosexitcode);
   end.
 {
+  $Log$
+  Revision 1.1  2001-04-25 22:40:07  peter
+    * compiler dependent utils in utils/ subdir
+
 }

+ 1580 - 0
compiler/utils/ppudump.pp

@@ -0,0 +1,1580 @@
+{
+    $Id$
+    Copyright (c) 1998-2000 by the FPC Development Team
+
+    Dumps the contents of a FPC unit file (PPU File)
+
+    This program 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 of the License, or
+    (at your option) any later version.
+
+    This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+{$ifdef TP}
+  {$N+,E+}
+{$endif}
+program pppdump;
+uses
+{$ifdef go32v2}
+  dpmiexcp,
+{$endif go32v2}
+  ppu;
+
+const
+  Version   = 'Version 1.10';
+  Title     = 'PPU-Analyser';
+  Copyright = 'Copyright (c) 1998-2000 by the Free Pascal Development Team';
+
+{ verbosity }
+  v_none           = $0;
+  v_header         = $1;
+  v_defs           = $2;
+  v_syms           = $4;
+  v_interface      = $8;
+  v_implementation = $10;
+  v_browser        = $20;
+  v_all            = $ff;
+
+var
+  ppufile     : pppufile;
+  space       : string;
+  read_member : boolean;
+  verbose     : longint;
+
+{****************************************************************************
+                          Helper Routines
+****************************************************************************}
+
+const has_errors : boolean = false;
+Procedure Error(const S : string);
+Begin
+   Writeln(S);
+   has_errors:=true;
+End;
+
+Function Target2Str(w:longint):string;
+type
+  ttarget = (target_none
+     ,target_i386_GO32V1,target_i386_GO32V2,target_i386_linux,
+      target_i386_OS2,target_i386_Win32
+     ,target_m68k_Amiga,target_m68k_Atari,target_m68k_Mac,
+      target_m68k_linux,target_m68k_PalmOS
+  );
+const
+  Targets : array[ttarget] of string[10]=('none',
+     'GO32V1','GO32V2','Linux-i386','OS/2','Win32',
+     'Amiga','Mac68k','Atari','Linux-m68k','PalmOs');
+begin
+  if w<=ord(high(ttarget)) then
+    Target2Str:=Targets[ttarget(w)]
+  else
+    Target2Str:='<Unknown>';
+end;
+
+
+Function Cpu2Str(w:longint):string;
+type
+  ttargetcpu=(no_cpu
+       ,i386,m68k,alpha
+  );
+const
+  CpuTxt : array[ttargetcpu] of string[5]=
+    ('none','i386','m68k','alpha');
+begin
+  if w<=ord(high(ttargetcpu)) then
+    Cpu2Str:=CpuTxt[ttargetcpu(w)]
+  else
+    Cpu2Str:='<Unknown>';
+end;
+
+
+function PPUFlags2Str(flags:longint):string;
+type
+  tflagopt=record
+    mask : longint;
+    str  : string[30];
+  end;
+const
+  flagopts=11;
+  flagopt : array[1..flagopts] of tflagopt=(
+    (mask: $1    ;str:'init'),
+    (mask: $2    ;str:'final'),
+    (mask: $4    ;str:'big_endian'),
+    (mask: $8    ;str:'dbx'),
+    (mask: $10   ;str:'browser'),
+    (mask: $20   ;str:'in_library'),
+    (mask: $40   ;str:'smart_linked'),
+    (mask: $80   ;str:'static_linked'),
+    (mask: $100  ;str:'shared_linked'),
+    (mask: $200  ;str:'local_browser'),
+    (mask: $400  ;str:'no_link')
+  );
+var
+  i : longint;
+  first  : boolean;
+  s : string;
+begin
+  s:='';
+  if flags<>0 then
+   begin
+     first:=true;
+     for i:=1to flagopts do
+      if (flags and flagopt[i].mask)<>0 then
+       begin
+         if first then
+           first:=false
+         else
+           s:=s+', ';
+         s:=s+flagopt[i].str;
+       end;
+   end
+  else
+   s:='none';
+  PPUFlags2Str:=s;
+end;
+
+
+const
+  HexTbl : array[0..15] of char='0123456789ABCDEF';
+function HexB(b:byte):string;
+begin
+  HexB[0]:=#2;
+  HexB[1]:=HexTbl[b shr 4];
+  HexB[2]:=HexTbl[b and $f];
+end;
+
+
+{****************************************************************************
+                             Read Routines
+****************************************************************************}
+
+Procedure ReadLinkContainer(const prefix:string);
+{
+  Read a serie of strings and write to the screen starting every line
+  with prefix
+}
+  function maskstr(m:longint):string;
+  const
+    { link options }
+    link_none    = $0;
+    link_allways = $1;
+    link_static  = $2;
+    link_smart   = $4;
+    link_shared  = $8;
+  var
+    s : string;
+  begin
+    s:='';
+    if (m and link_allways)<>0 then
+     s:=s+'always ';
+    if (m and link_static)<>0 then
+     s:=s+'static ';
+    if (m and link_smart)<>0 then
+     s:=s+'smart ';
+    if (m and link_shared)<>0 then
+     s:=s+'shared ';
+    maskstr:=s;
+  end;
+
+var
+  s : string;
+  m : longint;
+begin
+  while not ppufile^.endofentry do
+   begin
+     s:=ppufile^.getstring;
+     m:=ppufile^.getlongint;
+     WriteLn(prefix,s,' (',maskstr(m),')');
+   end;
+end;
+
+
+Procedure ReadContainer(const prefix:string);
+{
+  Read a serie of strings and write to the screen starting every line
+  with prefix
+}
+begin
+  while not ppufile^.endofentry do
+   WriteLn(prefix,ppufile^.getstring);
+end;
+
+
+Procedure ReadRef;
+begin
+  if (verbose and v_browser)=0 then
+   exit;
+  while (not ppufile^.endofentry) and (not ppufile^.error) do
+   Writeln(space,'        - Refered : ',ppufile^.getword,', (',ppufile^.getlongint,',',ppufile^.getword,')');
+end;
+
+
+Procedure ReadPosInfo;
+begin
+  Writeln(ppufile^.getword,' (',ppufile^.getlongint,',',ppufile^.getword,')');
+end;
+
+
+function readderef(const s:string;skipnil:boolean):boolean;
+type
+  tdereftype = (derefnil,derefaktrecordindex,derefaktstaticindex,
+                derefunit,derefrecord,derefindex,
+                dereflocal,derefpara,derefaktlocalindex);
+var
+  b : tdereftype;
+begin
+  readderef:=true;
+  repeat
+    b:=tdereftype(ppufile^.getbyte);
+    case b of
+      derefnil :
+        begin
+          if not skipnil then
+           writeln('nil');
+          readderef:=false;
+          break;
+        end;
+      derefaktrecordindex :
+        begin
+          writeln('AktRecord ',s,' ',ppufile^.getword);
+          break;
+        end;
+      derefaktstaticindex :
+        begin
+          writeln('AktStatic ',s,' ',ppufile^.getword);
+          break;
+        end;
+      derefaktlocalindex :
+        begin
+          writeln('AktLocal ',s,' ',ppufile^.getword);
+          break;
+        end;
+      derefunit :
+        begin
+          writeln('Unit ',ppufile^.getword);
+          break;
+        end;
+      derefrecord :
+        begin
+          write('RecordDef ',ppufile^.getword,', ');
+        end;
+      derefpara :
+        begin
+          write('Parameter of procdef ',ppufile^.getword,', ');
+        end;
+      dereflocal :
+        begin
+          write('Local of procdef ',ppufile^.getword,', ');
+        end;
+      derefindex :
+        begin
+          write(s,' ',ppufile^.getword,', ');
+        end;
+      else
+        begin
+          writeln('!! unsupported dereftyp: ',ord(b));
+          break;
+        end;
+    end;
+  until false;
+end;
+
+
+function readdefref:boolean;
+begin
+  readdefref:=readderef('Definition',false);
+end;
+
+
+function readsymref:boolean;
+begin
+  readsymref:=readderef('Symbol',false);
+end;
+
+
+procedure readtype;
+var
+  b1,b2 : boolean;
+begin
+  b1:=readderef('Definition',true);
+  b2:=readderef('Symbol',true);
+  if not(b1 or b2) then
+   Writeln('nil')
+  else
+   if (b1 and b2) then
+    Writeln('!! Type has both definition and symbol stored');
+end;
+
+
+procedure readsymlist(const s:string);
+begin
+  readdefref;
+  repeat
+    write(s);
+    if not readsymref then
+     break;
+  until false;
+end;
+
+
+procedure read_abstract_proc_def;
+type
+  tproccalloption=(pocall_none,
+    pocall_clearstack,    { Use IBM flat calling convention. (Used by GCC.) }
+    pocall_leftright,     { Push parameters from left to right }
+    pocall_cdecl,         { procedure uses C styled calling }
+    pocall_register,      { procedure uses register (fastcall) calling }
+    pocall_stdcall,       { procedure uses stdcall call }
+    pocall_safecall,      { safe call calling conventions }
+    pocall_palmossyscall, { procedure is a PalmOS system call }
+    pocall_system,
+    pocall_inline,        { Procedure is an assembler macro }
+    pocall_internproc,    { Procedure has compiler magic}
+    pocall_internconst    { procedure has constant evaluator intern }
+  );
+  tproccalloptions=set of tproccalloption;
+  tproctypeoption=(potype_none,
+    potype_proginit,     { Program initialization }
+    potype_unitinit,     { unit initialization }
+    potype_unitfinalize, { unit finalization }
+    potype_constructor,  { Procedure is a constructor }
+    potype_destructor,   { Procedure is a destructor }
+    potype_operator      { Procedure defines an operator }
+  );
+  tproctypeoptions=set of tproctypeoption;
+  tprocoption=(po_none,
+    po_classmethod,       { class method }
+    po_virtualmethod,     { Procedure is a virtual method }
+    po_abstractmethod,    { Procedure is an abstract method }
+    po_staticmethod,      { static method }
+    po_overridingmethod,  { method with override directive }
+    po_methodpointer,     { method pointer, only in procvardef, also used for 'with object do' }
+    po_containsself,      { self is passed explicit to the compiler }
+    po_interrupt,         { Procedure is an interrupt handler }
+    po_iocheck,           { IO checking should be done after a call to the procedure }
+    po_assembler,         { Procedure is written in assembler }
+    po_msgstr,            { method for string message handling }
+    po_msgint,            { method for int message handling }
+    po_exports,           { Procedure has export directive (needed for OS/2) }
+    po_external,          { Procedure is external (in other object or lib)}
+    po_savestdregs,       { save std regs cdecl and stdcall need that ! }
+    po_saveregisters      { save all registers }
+  );
+  tprocoptions=set of tprocoption;
+type
+  tproccallopt=record
+    mask : tproccalloption;
+    str  : string[30];
+  end;
+  tproctypeopt=record
+    mask : tproctypeoption;
+    str  : string[30];
+  end;
+  tprocopt=record
+    mask : tprocoption;
+    str  : string[30];
+  end;
+const
+  proccallopts=12;
+  proccallopt : array[1..proccallopts] of tproccallopt=(
+     (mask:pocall_none;         str:''),
+     (mask:pocall_clearstack;   str:'ClearStack'),
+     (mask:pocall_leftright;    str:'LeftRight'),
+     (mask:pocall_cdecl;        str:'Cdecl'),
+     (mask:pocall_register;     str:'Register'),
+     (mask:pocall_stdcall;      str:'StdCall'),
+     (mask:pocall_safecall;     str:'SafeCall'),
+     (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
+     (mask:pocall_system;       str:'System'),
+     (mask:pocall_inline;       str:'Inline'),
+     (mask:pocall_internproc;   str:'InternProc'),
+     (mask:pocall_internconst;  str:'InternConst')
+  );
+  proctypeopts=6;
+  proctypeopt : array[1..proctypeopts] of tproctypeopt=(
+     (mask:potype_proginit;    str:'ProgInit'),
+     (mask:potype_unitinit;    str:'UnitInit'),
+     (mask:potype_unitfinalize;str:'UnitFinalize'),
+     (mask:potype_constructor; str:'Constructor'),
+     (mask:potype_destructor;  str:'Destructor'),
+     (mask:potype_operator;    str:'Operator')
+  );
+  procopts=16;
+  procopt : array[1..procopts] of tprocopt=(
+     (mask:po_classmethod;     str:'ClassMethod'),
+     (mask:po_virtualmethod;   str:'VirtualMethod'),
+     (mask:po_abstractmethod;  str:'AbstractMethod'),
+     (mask:po_staticmethod;    str:'StaticMethod'),
+     (mask:po_overridingmethod;str:'OverridingMethod'),
+     (mask:po_methodpointer;   str:'MethodPointer'),
+     (mask:po_containsself;    str:'ContainsSelf'),
+     (mask:po_interrupt;       str:'Interrupt'),
+     (mask:po_iocheck;         str:'IOCheck'),
+     (mask:po_assembler;       str:'Assembler'),
+     (mask:po_msgstr;          str:'MsgStr'),
+     (mask:po_msgint;          str:'MsgInt'),
+     (mask:po_exports;         str:'Exports'),
+     (mask:po_external;        str:'External'),
+     (mask:po_savestdregs;     str:'SaveStdRegs'),
+     (mask:po_saveregisters;   str:'SaveRegisters')
+  );
+  tvarspez : array[0..2] of string[5]=('Value','Const','Var  ');
+var
+  proctypeoption  : tproctypeoption;
+  proccalloptions : tproccalloptions;
+  procoptions     : tprocoptions;
+  i,params : longint;
+  first    : boolean;
+begin
+  write(space,'      Return type : ');
+  readtype;
+  writeln(space,'         Fpu used : ',ppufile^.getbyte);
+  proctypeoption:=tproctypeoption(ppufile^.getlongint);
+  if proctypeoption<>potype_none then
+   begin
+     write(space,'       TypeOption : ');
+     first:=true;
+     for i:=1to proctypeopts do
+      if (proctypeopt[i].mask=proctypeoption) then
+       begin
+         if first then
+           first:=false
+         else
+           write(', ');
+         write(proctypeopt[i].str);
+       end;
+     writeln;
+   end;
+  ppufile^.getsmallset(proccalloptions);
+  if proccalloptions<>[] then
+   begin
+     write(space,'      CallOptions : ');
+     first:=true;
+     for i:=1to proccallopts do
+      if (proccallopt[i].mask in proccalloptions) then
+       begin
+         if first then
+           first:=false
+         else
+           write(', ');
+         write(proccallopt[i].str);
+       end;
+     writeln;
+   end;
+  ppufile^.getsmallset(procoptions);
+  if procoptions<>[] then
+   begin
+     write(space,'          Options : ');
+     first:=true;
+     for i:=1to procopts do
+      if (procopt[i].mask in procoptions) then
+       begin
+         if first then
+           first:=false
+         else
+           write(', ');
+         write(procopt[i].str);
+       end;
+     writeln;
+   end;
+  params:=ppufile^.getword;
+  writeln(space,' Nr of parameters : ',params);
+  if params>0 then
+   begin
+     repeat
+       write(space,'  - ',tvarspez[ppufile^.getbyte],' : ');
+       readtype;
+       write(space,'    Default : ');
+       readsymref;
+       dec(params);
+     until params=0;
+   end;
+end;
+
+
+procedure readcommonsym(const s:string);
+type
+  tsymoption=(sp_none,
+    sp_public,
+    sp_private,
+    sp_published,
+    sp_protected,
+    sp_forwarddef,
+    sp_static,
+    sp_primary_typesym    { this is for typesym, to know who is the primary symbol of a def }
+  );
+  tsymoptions=set of tsymoption;
+  tsymopt=record
+    mask : tsymoption;
+    str  : string[30];
+  end;
+const
+  symopts=7;
+  symopt : array[1..symopts] of tsymopt=(
+     (mask:sp_public;         str:'Public'),
+     (mask:sp_private;        str:'Private'),
+     (mask:sp_published;      str:'Published'),
+     (mask:sp_protected;      str:'Protected'),
+     (mask:sp_forwarddef;     str:'ForwardDef'),
+     (mask:sp_static;         str:'Static'),
+     (mask:sp_primary_typesym;str:'PrimaryTypeSym')
+  );
+var
+  symoptions : tsymoptions;
+  i      : longint;
+  first  : boolean;
+begin
+  writeln(space,'** Symbol Nr. ',ppufile^.getword,' **');
+  writeln(space,s,ppufile^.getstring);
+  ppufile^.getsmallset(symoptions);
+  if symoptions<>[] then
+   begin
+     write(space,'    File Pos: ');
+     readposinfo;
+     write(space,'  SymOptions: ');
+     first:=true;
+     for i:=1to symopts do
+      if (symopt[i].mask in symoptions) then
+       begin
+         if first then
+           first:=false
+         else
+           write(', ');
+         write(symopt[i].str);
+       end;
+     writeln;
+   end;
+end;
+
+
+procedure readcommondef(const s:string);
+begin
+  writeln(space,'** Definition Nr. ',ppufile^.getword,' **');
+  writeln(space,s);
+  write  (space,'      Type symbol : ');
+  readsymref;
+end;
+
+
+{****************************************************************************
+                             Read Symbols Part
+****************************************************************************}
+
+procedure readsymbols;
+Const
+  vo_is_C_var = 2;
+Type
+  absolutetyp = (tovar,toasm,toaddr);
+  tconsttyp = (constnone,
+    constord,conststring,constreal,constbool,
+    constint,constchar,constset,constpointer,constnil,
+    constresourcestring
+  );
+var
+  b      : byte;
+  pc     : pchar;
+  totalsyms,
+  symcnt,
+  i,j,len : longint;
+  l1,l2 : longint;
+begin
+  symcnt:=1;
+  with ppufile^ do
+   begin
+     if space<>'' then
+      Writeln(space,'-----------------------------');
+     if readentry=ibstartsyms then
+      begin
+        totalsyms:=getlongint;
+        Writeln(space,'Number of symbols : ',totalsyms);
+        Writeln(space,'Symtable datasize : ',getlongint);
+        Writeln(space,'Symtable alignment: ',getlongint);
+      end
+     else
+      begin
+        totalsyms:=-1;
+        Writeln('!! ibstartsym not found');
+      end;
+     repeat
+       b:=readentry;
+       if not (b in [iberror,ibendsyms]) then
+        inc(symcnt);
+       case b of
+
+         ibunitsym :
+           readcommonsym('Unit symbol ');
+
+         iblabelsym :
+           readcommonsym('Label symbol ');
+
+         ibtypesym :
+           begin
+             readcommonsym('Type symbol ');
+             write(space,' Result Type: ');
+             readtype;
+           end;
+
+         ibprocsym :
+           begin
+             readcommonsym('Procedure symbol ');
+             write(space,'  Definition: ');
+             readdefref;
+           end;
+
+         ibconstsym :
+           begin
+             readcommonsym('Constant symbol ');
+             b:=getbyte;
+             case tconsttyp(b) of
+               constord :
+                 begin
+                   write   (space,'OrdinalType: ');
+                   readtype;
+                   writeln (space,'      Value: ',getlongint)
+                 end;
+               constpointer :
+                 begin
+                   write (space,' Pointer Type: ');
+                   readtype;
+                   writeln (space,'      Value: ',getlongint)
+                 end;
+               conststring,
+               constresourcestring :
+                 begin
+                   len:=getlongint;
+                   getmem(pc,len+1);
+                   getdata(pc^,len);
+                   writeln(space,'      Length: ',len);
+                   writeln(space,'       Value: "',pc,'"');
+                   freemem(pc,len+1);
+                   if tconsttyp(b)=constresourcestring then
+                    writeln(space,'       Index: ',getlongint);
+                 end;
+               constreal :
+                 writeln(space,'       Value: ',getreal);
+               constbool :
+                 if getlongint<>0 then
+                   writeln (space,'      Value : True')
+                 else
+                   writeln (space,'      Value: False');
+               constint :
+                 begin
+                   l1:=getlongint;
+                   l2:=getlongint;
+                   writeln(space,'       Value: ',int64(l2 shl 32) or l1);
+                 end;
+               constchar :
+                 writeln(space,'       Value: "'+chr(getlongint)+'"');
+               constset :
+                 begin
+                   write (space,'     Set Type: ');
+                   readtype;
+                   for i:=1to 4 do
+                    begin
+                      write (space,'       Value: ');
+                      for j:=1to 8 do
+                       begin
+                         if j>1 then
+                          write(',');
+                         write(hexb(getbyte));
+                       end;
+                      writeln;
+                    end;
+                 end;
+               else
+                 Writeln ('!! Invalid unit format : Invalid const type encountered: ',b);
+             end;
+           end;
+
+         ibvarsym :
+           begin
+             readcommonsym('Variable symbol ');
+             writeln(space,'        Type: ',getbyte);
+             if read_member then
+               writeln(space,'     Address: ',getlongint);
+             write  (space,'    Var Type: ');
+             readtype;
+             i:=getlongint;
+             writeln(space,'     Options: ',i);
+             if (i and vo_is_C_var)<>0 then
+               writeln(space,' Mangledname: ',getstring);
+           end;
+
+         ibenumsym :
+           begin
+             readcommonsym('Enumeration symbol ');
+             write  (space,'  Definition: ');
+             readdefref;
+             writeln(space,'       Value: ',getlongint);
+           end;
+
+         ibsyssym :
+           begin
+             readcommonsym('Internal system symbol ');
+             writeln(space,' Internal Nr: ',getlongint);
+           end;
+
+         ibtypedconstsym :
+           begin
+             readcommonsym('Typed constant ');
+             write  (space,' Constant Type: ');
+             readtype;
+             writeln(space,'         Label: ',getstring);
+             writeln(space,'   ReallyConst: ',(getbyte<>0));
+           end;
+
+         ibabsolutesym :
+           begin
+             readcommonsym('Absolute variable symbol ');
+             writeln(space,'          Type: ',getbyte);
+             if read_member then
+               writeln(space,'       Address: ',getlongint);
+             write  (space,'      Var Type: ');
+             readtype;
+             writeln(space,'       Options: ',getlongint);
+             Write (space,'    Relocated to ');
+             b:=getbyte;
+             case absolutetyp(b) of
+               tovar :
+                 Writeln('Name : ',getstring);
+               toasm :
+                 Writeln('Assembler name : ',getstring);
+               toaddr :
+                 begin
+                   Write('Address : ',getlongint);
+                   WriteLn(' (Far: ',getbyte<>0,')');
+                 end;
+               else
+                 Writeln ('!! Invalid unit format : Invalid absolute type encountered: ',b);
+             end;
+           end;
+
+         ibpropertysym :
+           begin
+             readcommonsym('Property ');
+             i:=getlongint;
+             writeln(space,' PropOptions: ',i);
+             if (i and 32)>0 then
+              begin
+                write  (space,'OverrideProp: ');
+                readsymref;
+              end
+             else
+              begin
+                write  (space,'   Prop Type: ');
+                readtype;
+                writeln(space,'       Index: ',getlongint);
+                writeln(space,'     Default: ',getlongint);
+                write  (space,'  Index Type: ');
+                readtype;
+                write  (space,'  Readaccess: ');
+                readsymlist(space+'         Sym: ');
+                write  (space,' Writeaccess: ');
+                readsymlist(space+'         Sym: ');
+                write  (space,'Storedaccess: ');
+                readsymlist(space+'         Sym: ');
+              end;
+           end;
+
+         ibfuncretsym :
+           begin
+             readcommonsym('Func return value ');
+             write  (space,' Return Type: ');
+             readtype;
+             writeln(space,'     Address: ',getlongint);
+           end;
+
+         iberror :
+           begin
+             Writeln('!! Error in PPU');
+             exit;
+           end;
+
+         ibendsyms :
+           break;
+
+         else
+           WriteLn('!! Skipping unsupported PPU Entry in Symbols: ',b);
+       end;
+       if not EndOfEntry then
+        Writeln('!! Entry has more information stored');
+     until false;
+     if (totalsyms<>-1) and (symcnt-1<>totalsyms) then
+       Writeln('!! Only read ',symcnt-1,' of ',totalsyms,' symbols');
+   end;
+end;
+
+
+{****************************************************************************
+                         Read defintions Part
+****************************************************************************}
+
+procedure readdefinitions(start_read : boolean);
+type
+  tsettype  = (normset,smallset,varset);
+  tbasetype = (
+    uauto,uvoid,uchar,
+    u8bit,u16bit,u32bit,
+    s8bit,s16bit,s32bit,
+    bool8bit,bool16bit,bool32bit,
+    u64bit,s64bit,uwidechar
+  );
+  tobjectdeftype = (odt_none,
+    odt_class,
+    odt_object,
+    odt_interfacecom,
+    odt_interfacecorba,
+    odt_cppclass
+  );
+var
+  b : byte;
+  oldread_member : boolean;
+  totaldefs,l,j,
+  defcnt : longint;
+begin
+  defcnt:=0;
+  with ppufile^ do
+   begin
+     if space<>'' then
+      Writeln(space,'-----------------------------');
+     if not start_read then
+       if readentry=ibstartdefs then
+         begin
+           totaldefs:=getlongint;
+           Writeln(space,'Number of definitions: ',totaldefs);
+         end
+       else
+         begin
+           totaldefs:=-1;
+           Writeln('!! ibstartdef not found');
+         end;
+     repeat
+       b:=readentry;
+       if not (b in [iberror,ibenddefs]) then
+        inc(defcnt);
+       case b of
+
+         ibpointerdef :
+           begin
+             readcommondef('Pointer definition');
+             write  (space,'     Pointed Type : ');
+             readtype;
+             writeln(space,'           Is Far : ',(getbyte<>0));
+           end;
+
+         iborddef :
+           begin
+             readcommondef('Ordinal definition');
+             write  (space,'        Base type : ');
+             b:=getbyte;
+             case tbasetype(b) of
+               uauto     : writeln('uauto');
+               uvoid     : writeln('uvoid');
+               uchar     : writeln('uchar');
+               u8bit     : writeln('u8bit');
+               u16bit    : writeln('u16bit');
+               u32bit    : writeln('s32bit');
+               s8bit     : writeln('s8bit');
+               s16bit    : writeln('s16bit');
+               s32bit    : writeln('s32bit');
+               bool8bit  : writeln('bool8bit');
+               bool16bit : writeln('bool16bit');
+               bool32bit : writeln('bool32bit');
+               u64bit    : writeln('u64bit');
+               s64bit    : writeln('s64bit');
+               uwidechar : writeln('uwidechar');
+               else        writeln('!! Warning: Invalid base type ',b);
+             end;
+             writeln(space,'            Range : ',getlongint,' to ',getlongint);
+           end;
+
+         ibfloatdef :
+           begin
+             readcommondef('Float definition');
+             writeln(space,'       Float type : ',getbyte);
+           end;
+
+         ibarraydef :
+           begin
+             readcommondef('Array definition');
+             write  (space,'     Element type : ');
+             readtype;
+             write  (space,'       Range Type : ');
+             readtype;
+             writeln(space,'            Range : ',getlongint,' to ',getlongint);
+             writeln(space,'   Is Constructor : ',(getbyte<>0));
+           end;
+
+         ibprocdef :
+           begin
+             readcommondef('Procedure definition');
+             read_abstract_proc_def;
+             writeln(space,'    Used Register : ',getbyte);
+             writeln(space,'     Mangled name : ',getstring);
+             writeln(space,'           Number : ',getlongint);
+             write  (space,'             Next : ');
+             readdefref;
+             write  (space,'            Class : ');
+             readdefref;
+             write  (space,'         File Pos : ');
+             readposinfo;
+             space:='    '+space;
+             { parast }
+             readdefinitions(false);
+             readsymbols;
+             { localst }
+             {readdefinitions(false);
+             readsymbols;}
+             delete(space,1,4);
+           end;
+
+         ibprocvardef :
+           begin
+             readcommondef('Procedural type (ProcVar) definition');
+             read_abstract_proc_def;
+           end;
+
+         ibshortstringdef :
+           begin
+             readcommondef('ShortString definition');
+             writeln(space,'           Length : ',getbyte);
+           end;
+
+         ibwidestringdef :
+           begin
+             readcommondef('WideString definition');
+             writeln(space,'           Length : ',getlongint);
+           end;
+
+         ibansistringdef :
+           begin
+             readcommondef('AnsiString definition');
+             writeln(space,'           Length : ',getlongint);
+           end;
+
+         iblongstringdef :
+           begin
+             readcommondef('Longstring definition');
+             writeln(space,'           Length : ',getlongint);
+           end;
+
+         ibrecorddef :
+           begin
+             readcommondef('Record definition');
+             writeln(space,'             Size : ',getlongint);
+             {read the record definitions and symbols}
+             space:='    '+space;
+             oldread_member:=read_member;
+             read_member:=true;
+             readdefinitions(false);
+             readsymbols;
+             read_member:=oldread_member;
+             Delete(space,1,4);
+           end;
+
+         ibobjectdef :
+           begin
+             readcommondef('Object/Class definition');
+             b:=getbyte;
+             write  (space,'             Type : ');
+             case tobjectdeftype(b) of
+               odt_class          : writeln('class');
+               odt_object         : writeln('object');
+               odt_interfacecom   : writeln('interfacecom');
+               odt_interfacecorba : writeln('interfacecorba');
+               odt_cppclass       : writeln('cppclass');
+               else                 writeln('!! Warning: Invalid object type ',b);
+             end;
+             writeln(space,'             Size : ',getlongint);
+             writeln(space,'       Vmt offset : ',getlongint);
+             writeln(space,'    Name of Class : ',getstring);
+             write(space,  '   Ancestor Class : ');
+             readdefref;
+             writeln(space,'          Options : ',getlongint);
+             writeln(space,'         Has RTTI : ',(getbyte<>0));
+
+             if tobjectdeftype(b) in [odt_interfacecom,odt_interfacecorba] then
+               begin
+                  writeln(space,'       GUID Valid : ',(getbyte<>0));
+                  { IIDGUID }
+                  for j:=1to 16 do
+                   getbyte;
+                  writeln(space,'       IID String : ',getstring);
+                  writeln(space,'  Last VTable idx : ',getlongint);
+               end;
+
+             if tobjectdeftype(b) in [odt_class,odt_interfacecorba] then
+              begin
+                l:=getlongint;
+                writeln(space,'  Impl Intf Count : ',l);
+                for j:=1 to l do
+                 begin
+                   write  (space,'  - Definition : ');
+                   readdefref;
+                   writeln(space,'       IOffset : ',getlongint);
+                 end;
+              end;
+
+           {read the record definitions and symbols}
+             space:='    '+space;
+             oldread_member:=read_member;
+             read_member:=true;
+             readdefinitions(false);
+             readsymbols;
+             read_member:=oldread_member;
+             Delete(space,1,4);
+           end;
+
+         ibfiledef :
+           begin
+             ReadCommonDef('File definition');
+             write  (space,'             Type : ');
+             case getbyte of
+              0 : writeln('Text');
+              1 : begin
+                    writeln('Typed');
+                    write  (space,'      File of Type : ');
+                    Readtype;
+                  end;
+              2 : writeln('Untyped');
+             end;
+           end;
+
+         ibformaldef :
+           readcommondef('Generic Definition (void-typ)');
+
+         ibenumdef :
+           begin
+             readcommondef('Enumeration type definition');
+             write(space,'Base enumeration type : ');
+             readdefref;
+             writeln(space,' Smallest element : ',getlongint);
+             writeln(space,'  Largest element : ',getlongint);
+             writeln(space,'             Size : ',getlongint);
+           end;
+
+         ibclassrefdef :
+           begin
+             readcommondef('Class reference definition');
+             write  (space,'    Pointed Type : ');
+             readtype;
+           end;
+
+         ibsetdef :
+           begin
+             readcommondef('Set definition');
+             write  (space,'     Element type : ');
+             readtype;
+             b:=getbyte;
+             case tsettype(b) of
+               smallset : writeln(space,'  Set with 32 Elements');
+               normset  : writeln(space,'  Set with 256 Elements');
+               varset   : writeln(space,'  Set with ',getlongint,' Elements');
+               else       writeln('!! Warning: Invalid set type ',b);
+             end;
+           end;
+
+
+         ibvariantdef :
+           begin
+             readcommondef('Variant definition');
+           end;
+
+         iberror :
+           begin
+             Writeln('!! Error in PPU');
+             exit;
+           end;
+
+         ibenddefs :
+           break;
+
+         else
+           WriteLn('!! Skipping unsupported PPU Entry in definitions: ',b);
+       end;
+       if not EndOfEntry then
+        Writeln('!! Entry has more information stored');
+     until false;
+     if (totaldefs<>-1) and (defcnt<>totaldefs) then
+      Writeln('!! Only read ',defcnt,' of ',totaldefs,' definitions');
+   end;
+end;
+
+
+{****************************************************************************
+                           Read General Part
+****************************************************************************}
+
+procedure readinterface;
+var
+  b : byte;
+  sourcenumber,
+  unitnumber : word;
+  ucrc,uintfcrc : longint;
+begin
+  with ppufile^ do
+   begin
+     repeat
+       b:=readentry;
+       case b of
+
+         ibmodulename :
+           Writeln('Module Name: ',getstring);
+
+         ibsourcefiles :
+           begin
+             sourcenumber:=1;
+             while not EndOfEntry do
+              begin
+                Writeln('Source file ',sourcenumber,' : ',getstring);
+                inc(sourcenumber);
+              end;
+           end;
+
+         ibusedmacros :
+           begin
+             while not EndOfEntry do
+              begin
+                Write('Conditional ',getstring);
+                b:=getbyte;
+                if boolean(b)=true then
+                  write(' defined at startup')
+                else
+                  write(' not defined at startup');
+                b:=getbyte;
+                if boolean(b)=true then
+                  writeln(' was used')
+                else
+                  writeln;
+              end;
+           end;
+         ibloadunit :
+           begin
+             unitnumber:=1;
+             while not EndOfEntry do
+              begin
+                write('Uses unit: ',getstring,' (Number: ',unitnumber,')');
+                ucrc:=getlongint;
+                uintfcrc:=getlongint;
+                write(' (Crc: ',ucrc,', IntfcCrc: ',uintfcrc,')');
+                if getbyte<>0 then
+                 writeln(' (interface)')
+                else
+                 writeln(' (implementation)');
+                inc(unitnumber);
+              end;
+           end;
+
+         iblinkunitofiles :
+           ReadLinkContainer('Link unit object file: ');
+
+         iblinkunitstaticlibs :
+           ReadLinkContainer('Link unit static lib: ');
+
+         iblinkunitsharedlibs :
+           ReadLinkContainer('Link unit shared lib: ');
+
+         iblinkotherofiles :
+           ReadLinkContainer('Link other object file: ');
+
+         iblinkotherstaticlibs :
+           ReadLinkContainer('Link other static lib: ');
+
+         iblinkothersharedlibs :
+           ReadLinkContainer('Link other shared lib: ');
+
+         iberror :
+           begin
+             Writeln('Error in PPU');
+             exit;
+           end;
+
+         ibendinterface :
+           break;
+
+         else
+           WriteLn('!! Skipping unsupported PPU Entry in General Part: ',b);
+       end;
+     until false;
+   end;
+end;
+
+
+
+{****************************************************************************
+                        Read Implementation Part
+****************************************************************************}
+
+procedure readimplementation;
+var
+  b : byte;
+begin
+  with ppufile^ do
+   begin
+     repeat
+       b:=readentry;
+       case b of
+         iberror :
+           begin
+             Writeln('Error in PPU');
+             exit;
+           end;
+         ibendimplementation :
+           break;
+         else
+           WriteLn('!! Skipping unsupported PPU Entry in Implementation: ',b);
+       end;
+     until false;
+   end;
+end;
+
+
+{****************************************************************************
+                            Read Browser Part
+****************************************************************************}
+
+procedure readbrowser;
+var
+  b : byte;
+const indent : string = '';
+begin
+  Writeln(indent,'Start of symtable browser');
+  indent:=indent+'**';
+  with ppufile^ do
+   begin
+     repeat
+       b:=readentry;
+       case b of
+        ibbeginsymtablebrowser :
+                         { here we must read object and record symtables !! }
+                    begin
+                      indent:=indent+'  ';
+                      Writeln(indent,'Record/Object symtable');
+                      readbrowser;
+                      Indent:=Copy(Indent,1,Length(Indent)-2);
+                    end;
+            ibsymref : begin
+                         readsymref;
+                         readref;
+                       end;
+            ibdefref : begin
+                         readdefref;
+                         readref;
+                         if (ppufile^.header.flags and uf_local_browser)<>0 then
+                           begin
+                             { parast and localst }
+                             indent:=indent+'  ';
+                             Writeln(indent,'Parasymtable for function');
+                             readdefinitions(false);
+                             readsymbols;
+                             b:=ppufile^.readentry;
+                             if b=ibbeginsymtablebrowser then
+                               readbrowser;
+                             Writeln(indent,'Localsymtable for function');
+                             readdefinitions(false);
+                             readsymbols;
+                             b:=ppufile^.readentry;
+                             if b=ibbeginsymtablebrowser then
+                               readbrowser;
+                             Indent:=Copy(Indent,1,Length(Indent)-2);
+                           end;
+                       end;
+             iberror : begin
+                         Writeln('Error in PPU');
+                         exit;
+                       end;
+        ibendsymtablebrowser : break;
+       else
+        begin
+        WriteLn('!! Skipping unsupported PPU Entry in Browser: ',b);
+        Halt;
+        end;
+       end;
+     until false;
+   end;
+  Indent:=Copy(Indent,1,Length(Indent)-2);
+  Writeln(Indent,'End of symtable browser');
+end;
+
+
+
+
+procedure dofile (filename : string);
+var
+  b,unitindex : byte;
+begin
+{ reset }
+  space:='';
+{ fix filename }
+  if pos('.',filename)=0 then
+   filename:=filename+'.ppu';
+  ppufile:=new(pppufile,Init(filename));
+  if not ppufile^.open then
+   begin
+     writeln ('IO-Error when opening : ',filename,', Skipping');
+     exit;
+   end;
+{ PPU File is open, check for PPU Id }
+  if not ppufile^.CheckPPUID then
+   begin
+     writeln(Filename,' : Not a valid PPU file, Skipping');
+     exit;
+   end;
+{ Check PPU Version }
+  Writeln('Analyzing ',filename,' (v',ppufile^.GetPPUVersion,')');
+  if ppufile^.GetPPUVersion<16 then
+   begin
+     writeln(Filename,' : Old PPU Formats (<v16) are not supported, Skipping');
+     exit;
+   end;
+{ Write PPU Header Information }
+  if (verbose and v_header)<>0 then
+   begin
+     Writeln;
+     Writeln('Header');
+     Writeln('-------');
+     with ppufile^.header do
+      begin
+        Writeln('Compiler version        : ',hi(ppufile^.header.compiler and $ff),'.',lo(ppufile^.header.compiler));
+        WriteLn('Target processor        : ',Cpu2Str(cpu));
+        WriteLn('Target operating system : ',Target2Str(target));
+        Writeln('Unit flags              : ',PPUFlags2Str(flags));
+        Writeln('FileSize (w/o header)   : ',size);
+        Writeln('Checksum                : ',checksum);
+        Writeln('Interface Checksum      : ',interface_checksum);
+      end;
+   end;
+{read the general stuff}
+  if (verbose and v_interface)<>0 then
+   begin
+     Writeln;
+     Writeln('Interface section');
+     Writeln('------------------');
+     readinterface;
+   end
+  else
+   ppufile^.skipuntilentry(ibendinterface);
+{read the definitions}
+  if (verbose and v_defs)<>0 then
+   begin
+     Writeln;
+     Writeln('Interface definitions');
+     Writeln('----------------------');
+     readdefinitions(false);
+   end
+  else
+   ppufile^.skipuntilentry(ibenddefs);
+{read the symbols}
+  if (verbose and v_syms)<>0 then
+   begin
+     Writeln;
+     Writeln('Interface Symbols');
+     Writeln('------------------');
+     readsymbols;
+   end
+  else
+   ppufile^.skipuntilentry(ibendsyms);
+{read the implementation stuff}
+{ Not used at the moment (PFV)
+  if (verbose and v_implementation)<>0 then
+   begin
+     Writeln;
+     Writeln('Implementation section');
+     Writeln('-----------------------');
+     readimplementation;
+   end
+  else}
+   ppufile^.skipuntilentry(ibendimplementation);
+{read the static browser units stuff}
+  if (ppufile^.header.flags and uf_local_browser)<>0 then
+   begin
+     if (verbose and v_defs)<>0 then
+      begin
+        Writeln;
+        Writeln('Static definitions');
+        Writeln('----------------------');
+        readdefinitions(false);
+      end
+     else
+      ppufile^.skipuntilentry(ibenddefs);
+   {read the symbols}
+     if (verbose and v_syms)<>0 then
+      begin
+        Writeln;
+        Writeln('Static Symbols');
+        Writeln('------------------');
+        readsymbols;
+      end;
+   end;
+{read the browser units stuff}
+  if (ppufile^.header.flags and uf_has_browser)<>0 then
+   begin
+     if (verbose and v_browser)<>0 then
+      begin
+        Writeln;
+        Writeln('Browser section');
+        Writeln('---------------');
+        UnitIndex:=0;
+        repeat
+          b:=ppufile^.readentry;
+          if b = ibendbrowser then break;
+          if b=ibbeginsymtablebrowser then
+            begin
+               Writeln('Unit ',UnitIndex);
+               readbrowser;
+               Inc(UnitIndex);
+            end
+          else
+            Writeln('Wrong end browser entry ',b,' should be ',ibendbrowser);
+        until false;
+      end;
+   end;
+{read the static browser units stuff}
+  if (ppufile^.header.flags and uf_local_browser)<>0 then
+   begin
+     if (verbose and v_browser)<>0 then
+      begin
+        Writeln;
+        Writeln('Static browser section');
+        Writeln('---------------');
+        b:=ppufile^.readentry;
+        if b=ibbeginsymtablebrowser then
+          begin
+             Writeln('Unit ',UnitIndex);
+             readbrowser;
+             Inc(UnitIndex);
+          end
+        else
+          Writeln('Wrong end browser entry ',b,' should be ',ibendbrowser);
+      end;
+   end;
+{shutdown ppufile}
+  ppufile^.close;
+  dispose(ppufile,done);
+  Writeln;
+end;
+
+
+
+procedure help;
+begin
+  writeln('usage: ppudump [options] <filename1> <filename2>...');
+  writeln;
+  writeln('[options] can be:');
+  writeln('    -V<verbose>  Set verbosity to <verbose>');
+  writeln('                   H - Show header info');
+  writeln('                   I - Show interface');
+  writeln('                   M - Show implementation');
+  writeln('                   S - Show interface symbols');
+  writeln('                   D - Show interface definitions');
+  writeln('                   B - Show browser info');
+  writeln('                   A - Show all');
+  writeln('    -?           This helpscreen');
+  halt;
+end;
+
+var
+  startpara,
+  nrfile,i  : longint;
+  para      : string;
+begin
+  writeln(Title+' '+Version);
+  writeln(Copyright);
+  writeln;
+  if paramcount<1 then
+   begin
+     writeln('usage: dumpppu [options] <filename1> <filename2>...');
+     halt(1);
+   end;
+{ turn verbose on by default }
+  verbose:=v_all;
+{ read options }
+  startpara:=1;
+  while copy(paramstr(startpara),1,1)='-' do
+   begin
+     para:=paramstr(startpara);
+     case upcase(para[2]) of
+      'V' : begin
+              verbose:=0;
+              for i:=3to length(para) do
+               case upcase(para[i]) of
+                'H' : verbose:=verbose or v_header;
+                'I' : verbose:=verbose or v_interface;
+                'M' : verbose:=verbose or v_implementation;
+                'D' : verbose:=verbose or v_defs;
+                'S' : verbose:=verbose or v_syms;
+                'B' : verbose:=verbose or v_browser;
+                'A' : verbose:=verbose or v_all;
+               end;
+            end;
+      '?' : help;
+     end;
+     inc(startpara);
+   end;
+{ process files }
+  for nrfile:=startpara to paramcount do
+   dofile (paramstr(nrfile));
+  if has_errors then
+    Halt(1);
+end.
+{
+  $Log$
+  Revision 1.1  2001-04-25 22:40:07  peter
+    * compiler dependent utils in utils/ subdir
+
+  Revision 1.5  2001/04/10 21:21:41  peter
+    * variantdef support
+    * propertysym fixed
+
+  Revision 1.4  2001/04/04 22:42:59  peter
+    * updated for new objectdef with interfaces
+
+  Revision 1.3  2000/09/09 19:46:40  peter
+    * show dataalignment
+
+  Revision 1.2  2000/08/13 12:58:06  peter
+    * updated for ppu additions
+
+  Revision 1.1  2000/07/13 10:16:22  michael
+  + Initial import
+
+  Revision 1.15  2000/07/04 19:05:54  peter
+    * be optimistic: version 1.00 for some utils
+
+  Revision 1.14  2000/02/09 16:44:14  peter
+    * log truncated
+
+  Revision 1.13  2000/01/23 16:34:36  peter
+    * updated for new aktlocalindex
+
+  Revision 1.12  2000/01/07 16:46:03  daniel
+    * copyright 2000
+
+  Revision 1.11  1999/11/30 10:35:37  peter
+    * support new readtype
+
+  Revision 1.10  1999/11/08 14:06:45  florian
+    + indexref of propertysym is handle too now
+
+  Revision 1.9  1999/08/31 16:07:37  pierre
+   + support for writeusedmacros
+
+  Revision 1.8  1999/08/15 10:47:14  peter
+    * updates for new options
+
+  Revision 1.7  1999/08/13 21:25:35  peter
+    * updated flags
+
+  Revision 1.6  1999/07/27 23:45:29  peter
+    * updated for typesym writing
+
+}

+ 280 - 0
compiler/utils/ppufiles.pp

@@ -0,0 +1,280 @@
+{
+    $Id$
+    Copyright (c) 1999-2000 by Peter Vreman
+
+    List files needed by PPU
+
+    This program 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 of the License, or
+    (at your option) any later version.
+
+    This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+Program ppufiles;
+
+uses
+  dos,
+  ppu;
+
+const
+  Version   = 'Version 1.00';
+  Title     = 'PPU-Files';
+  Copyright = 'Copyright (c) 1999-2000 by the Free Pascal Development Team';
+
+  PPUExt = 'ppu';
+
+type
+  poutfile = ^toutfile;
+  toutfile = record
+    name : string;
+    next : poutfile;
+  end;
+
+var
+  skipdup,
+  showstatic,
+  showshared,
+  showobjects : boolean;
+
+  OutFiles    : poutfile;
+
+
+{*****************************************************************************
+                                 Helpers
+*****************************************************************************}
+
+Procedure Error(const s:string;stop:boolean);
+{
+  Write an error message to stderr
+}
+begin
+{$ifdef FPC}
+  writeln(stderr,s);
+{$else}
+  writeln(s);
+{$endif}
+  if stop then
+   halt(1);
+end;
+
+
+Function AddExtension(Const HStr,ext:String):String;
+{
+  Return a filename which will have extension ext added if no
+  extension is found
+}
+var
+  j : longint;
+begin
+  j:=length(Hstr);
+  while (j>0) and (Hstr[j]<>'.') do
+   dec(j);
+  if j=0 then
+   AddExtension:=Hstr+'.'+Ext
+  else
+   AddExtension:=HStr;
+end;
+
+
+Function SplitPath(Const HStr:String):String;
+var
+  i : longint;
+begin
+  i:=Length(Hstr);
+  while (i>0) and not(Hstr[i] in ['\','/']) do
+   dec(i);
+  SplitPath:=Copy(Hstr,1,i);
+end;
+
+
+Procedure AddFile(const s:string);
+var
+  p : poutfile;
+begin
+  p:=nil;
+  if skipdup then
+   begin
+     p:=outfiles;
+     while assigned(p) do
+      begin
+        if s=p^.name then
+         break;
+        p:=p^.next;
+      end;
+   end;
+  if not assigned(p) then
+   begin
+     new(p);
+     p^.name:=s;
+     p^.next:=outfiles;
+     outfiles:=p;
+   end;
+end;
+
+
+Function DoPPU(const PPUFn:String):Boolean;
+{
+  Convert one file (in Filename) to library format.
+  Return true if successful, false otherwise.
+}
+Var
+  inppu  : pppufile;
+  b      : byte;
+
+  procedure showfiles;
+  begin
+    while not inppu^.endofentry do
+     begin
+       AddFile(inppu^.getstring);
+       inppu^.getlongint;
+     end;
+  end;
+
+begin
+  DoPPU:=false;
+  inppu:=new(pppufile,init(PPUFn));
+  if not inppu^.open then
+   begin
+     dispose(inppu,done);
+     Error('Error: Could not open : '+PPUFn,false);
+     Exit;
+   end;
+{ Check the ppufile }
+  if not inppu^.CheckPPUId then
+   begin
+     dispose(inppu,done);
+     Error('Error: Not a PPU File : '+PPUFn,false);
+     Exit;
+   end;
+  if inppu^.GetPPUVersion<CurrentPPUVersion then
+   begin
+     dispose(inppu,done);
+     Error('Error: Wrong PPU Version : '+PPUFn,false);
+     Exit;
+   end;
+{ read until the object files are found }
+  repeat
+    b:=inppu^.readentry;
+    case b of
+      ibendinterface,
+      ibend :
+        break;
+      iblinkunitstaticlibs :
+        if showstatic then
+         showfiles;
+      iblinkunitsharedlibs :
+        if showshared then
+         showfiles;
+      iblinkunitofiles :
+        if showobjects then
+         showfiles;
+    end;
+  until false;
+  dispose(inppu,done);
+  DoPPU:=True;
+end;
+
+
+
+var
+  i,parafile : longint;
+  dir        : SearchRec;
+  s,InFile   : String;
+  p          : poutfile;
+begin
+{ defaults }
+  skipdup:=true;
+{ options }
+  i:=1;
+  while (i<=paramcount) do
+   begin
+     s:=paramstr(i);
+     if s[1]<>'-' then
+      break;
+     case upcase(s[2]) of
+      'L' : showshared:=true;
+      'S' : showstatic:=true;
+      'O' : showobjects:=true;
+      'A' : skipdup:=false;
+      '?','H' :
+        begin
+          writeln('usage: ppufiles [options] <files>');
+          writeln('options:');
+          writeln('  -A  Show all files (don''t remove duplicates)');
+          writeln('  -L  Show only shared libraries');
+          writeln('  -S  Show only static libraries');
+          writeln('  -O  Show only object files');
+          writeln('  -H  This helpscreen');
+        end;
+     end;
+     inc(i);
+   end;
+  { default shows everything }
+  if i=1 then
+   begin
+     showshared:=true;
+     showstatic:=true;
+     showobjects:=true;
+   end;
+{ files }
+  parafile:=i;
+  for i:=parafile to ParamCount do
+   begin
+     InFile:=AddExtension(ParamStr(i),PPUExt);
+     FindFirst(InFile,$20,Dir);
+     while (DosError=0) do
+      begin
+        DoPPU(SplitPath(InFile)+Dir.Name);
+        FindNext(Dir);
+      end;
+{$ifdef fpc}
+     FindClose(Dir);
+{$endif}
+   end;
+{ Display the files }
+  while assigned(outfiles) do
+   begin
+     p:=outfiles;
+     write(outfiles^.name);
+     outfiles:=outfiles^.next;
+     dispose(p);
+     if assigned(outfiles) then
+      write(' ');
+   end;
+end.
+{
+  $Log$
+  Revision 1.1  2001-04-25 22:40:07  peter
+    * compiler dependent utils in utils/ subdir
+
+  Revision 1.2  2000/11/06 13:16:19  michael
+  + merged fixes from Peter
+
+  Revision 1.1.2.1  2000/11/06 13:14:48  michael
+  + Fixes from Peter for slashes in filenames
+
+  Revision 1.1  2000/07/13 10:16:22  michael
+  + Initial import
+
+  Revision 1.4  2000/07/04 19:05:54  peter
+    * be optimistic: version 1.00 for some utils
+
+  Revision 1.3  2000/01/24 12:32:22  daniel
+    * use a linkedlist instead of ansistring
+
+  Revision 1.2  2000/01/07 16:46:04  daniel
+    * copyright 2000
+
+  Revision 1.1  1999/11/23 09:44:41  peter
+    * initial version
+
+}

+ 647 - 0
compiler/utils/ppumove.pp

@@ -0,0 +1,647 @@
+{
+    $Id$
+    Copyright (c) 1999-2000 by the FPC Development Team
+
+    Add multiple FPC units into a static/shared library
+
+    This program 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 of the License, or
+    (at your option) any later version.
+
+    This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+{$ifndef TP}
+  {$H+}
+{$endif}
+Program ppumove;
+uses
+{$ifdef unix}
+  unix,
+{$else unix}
+  dos,
+{$endif unix}
+  ppu,
+  getopts;
+
+const
+  Version   = 'Version 1.00';
+  Title     = 'PPU-Mover';
+  Copyright = 'Copyright (c) 1998-2000 by the Free Pascal Development Team';
+
+  ShortOpts = 'o:e:d:qhsvbw';
+  BufSize = 4096;
+  PPUExt = 'ppu';
+  ObjExt = 'o';
+  StaticLibExt ='a';
+{$ifdef unix}
+  SharedLibExt ='so';
+  BatchExt     ='.sh';
+{$else}
+  SharedLibExt ='dll';
+  BatchExt     ='.bat';
+{$endif unix}
+
+  { link options }
+  link_none    = $0;
+  link_allways = $1;
+  link_static  = $2;
+  link_smart   = $4;
+  link_shared  = $8;
+
+Type
+  PLinkOEnt = ^TLinkOEnt;
+  TLinkOEnt = record
+    Name : string;
+    Next : PLinkOEnt;
+  end;
+
+Var
+  ArBin,LDBin,StripBin,
+  OutputFile,
+  OutputFileForLink,  { the name of the output file needed when linking }
+  DestPath,
+  PPLExt,
+  LibExt      : string;
+  Batch,
+  Quiet,
+  MakeStatic  : boolean;
+  Buffer      : Pointer;
+  ObjFiles    : PLinkOEnt;
+  BatchFile   : Text;
+
+{*****************************************************************************
+                                 Helpers
+*****************************************************************************}
+
+Procedure Error(const s:string;stop:boolean);
+{
+  Write an error message to stderr
+}
+begin
+{$ifdef FPC}
+  writeln(stderr,s);
+{$else}
+  writeln(s);
+{$endif}
+  if stop then
+   halt(1);
+end;
+
+
+function Shell(const s:string):longint;
+{
+  Run a shell commnad and return the exitcode
+}
+begin
+  if Batch then
+   begin
+     Writeln(BatchFile,s);
+     Shell:=0;
+     exit;
+   end;
+{$ifdef unix}
+  Shell:=unix.shell(s);
+{$else}
+  exec(getenv('COMSPEC'),'/C '+s);
+  Shell:=DosExitCode;
+{$endif}
+end;
+
+
+Function FileExists (Const F : String) : Boolean;
+{
+  Returns True if the file exists, False if not.
+}
+Var
+{$ifdef unix}
+  info : Stat;
+{$else}
+  info : searchrec;
+{$endif}
+begin
+{$ifdef unix}
+  FileExists:=FStat (F,Info);
+{$else}
+  FindFirst (F,anyfile,Info);
+  FileExists:=DosError=0;
+{$endif}
+end;
+
+
+Function AddExtension(Const HStr,ext:String):String;
+{
+  Return a filename which will have extension ext added if no
+  extension is found
+}
+var
+  j : longint;
+begin
+  j:=length(Hstr);
+  while (j>0) and (Hstr[j]<>'.') do
+   dec(j);
+  if j=0 then
+   AddExtension:=Hstr+'.'+Ext
+  else
+   AddExtension:=HStr;
+end;
+
+
+Function ForceExtension(Const HStr,ext:String):String;
+{
+  Return a filename which certainly has the extension ext
+}
+var
+  j : longint;
+begin
+  j:=length(Hstr);
+  while (j>0) and (Hstr[j]<>'.') do
+   dec(j);
+  if j=0 then
+   j:=255;
+  ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
+end;
+
+
+Procedure AddToLinkFiles(const S : String);
+{
+  Adds a filename to a list of object files to link to.
+  No duplicates allowed.
+}
+Var
+  P : PLinKOEnt;
+begin
+  P:=ObjFiles;
+  { Don't add files twice }
+  While (P<>nil) and (p^.name<>s) do
+    p:=p^.next;
+  if p=nil then
+   begin
+     new(p);
+     p^.next:=ObjFiles;
+     p^.name:=s;
+     ObjFiles:=P;
+   end;
+end;
+
+
+Function ExtractLib(const libfn:string):string;
+{
+  Extract a static library libfn and return the files with a
+  wildcard
+}
+var
+  n : namestr;
+  d : dirstr;
+  e : extstr;
+begin
+{ create the temp dir first }
+  fsplit(libfn,d,n,e);
+  {$I-}
+   mkdir(n+'.sl');
+  {$I+}
+  if ioresult<>0 then;
+{ Extract }
+  if Shell(arbin+' x '+libfn)<>0 then
+   Error('Fatal: Error running '+arbin,true);
+{ Remove the lib file, it's extracted so it can be created with ease }
+  if PPLExt=PPUExt then
+   Shell('rm '+libfn);
+{$ifdef unix}
+  ExtractLib:=n+'.sl/*';
+{$else}
+  ExtractLib:=n+'.sl\*';
+{$endif}
+end;
+
+
+Function DoPPU(const PPUFn,PPLFn:String):Boolean;
+{
+  Convert one file (in Filename) to library format.
+  Return true if successful, false otherwise.
+}
+Var
+  inppu,
+  outppu : pppufile;
+  b,
+  untilb : byte;
+  l,m    : longint;
+  f      : file;
+  s      : string;
+begin
+  DoPPU:=false;
+  If Not Quiet then
+   Write ('Processing ',PPUFn,'...');
+  inppu:=new(pppufile,init(PPUFn));
+  if not inppu^.open then
+   begin
+     dispose(inppu,done);
+     Error('Error: Could not open : '+PPUFn,false);
+     Exit;
+   end;
+{ Check the ppufile }
+  if not inppu^.CheckPPUId then
+   begin
+     dispose(inppu,done);
+     Error('Error: Not a PPU File : '+PPUFn,false);
+     Exit;
+   end;
+  if inppu^.GetPPUVersion<CurrentPPUVersion then
+   begin
+     dispose(inppu,done);
+     Error('Error: Wrong PPU Version : '+PPUFn,false);
+     Exit;
+   end;
+{ No .o file generated for this ppu, just skip }
+  if (inppu^.header.flags and uf_no_link)<>0 then
+   begin
+     dispose(inppu,done);
+     If Not Quiet then
+      Writeln (' No files.');
+     DoPPU:=true;
+     Exit;
+   end;
+{ Already a lib? }
+  if (inppu^.header.flags and uf_in_library)<>0 then
+   begin
+     dispose(inppu,done);
+     Error('Error: PPU is already in a library : '+PPUFn,false);
+     Exit;
+   end;
+{ We need a static linked unit }
+  if (inppu^.header.flags and uf_static_linked)=0 then
+   begin
+     dispose(inppu,done);
+     Error('Error: PPU is not static linked : '+PPUFn,false);
+     Exit;
+   end;
+{ Create the new ppu }
+  if PPUFn=PPLFn then
+   outppu:=new(pppufile,init('ppumove.$$$'))
+  else
+   outppu:=new(pppufile,init(PPLFn));
+  outppu^.create;
+{ Create new header, with the new flags }
+  outppu^.header:=inppu^.header;
+  outppu^.header.flags:=outppu^.header.flags or uf_in_library;
+  if MakeStatic then
+   outppu^.header.flags:=outppu^.header.flags or uf_static_linked
+  else
+   outppu^.header.flags:=outppu^.header.flags or uf_shared_linked;
+{ read until the object files are found }
+  untilb:=iblinkunitofiles;
+  repeat
+    b:=inppu^.readentry;
+    if b in [ibendinterface,ibend] then
+     begin
+       dispose(inppu,done);
+       dispose(outppu,done);
+       Error('Error: No files to be linked found : '+PPUFn,false);
+       Exit;
+     end;
+    if b<>untilb then
+     begin
+       repeat
+         inppu^.getdatabuf(buffer^,bufsize,l);
+         outppu^.putdata(buffer^,l);
+       until l<bufsize;
+       outppu^.writeentry(b);
+     end;
+  until (b=untilb);
+{ we have now reached the section for the files which need to be added,
+  now add them to the list }
+  case b of
+    iblinkunitofiles :
+      begin
+        { add all o files, and save the entry when not creating a static
+          library to keep staticlinking possible }
+        while not inppu^.endofentry do
+         begin
+           s:=inppu^.getstring;
+           m:=inppu^.getlongint;
+           if not MakeStatic then
+            begin
+              outppu^.putstring(s);
+              outppu^.putlongint(m);
+            end;
+           AddToLinkFiles(s);
+         end;
+        if not MakeStatic then
+         outppu^.writeentry(b);
+      end;
+{    iblinkunitstaticlibs :
+      begin
+        AddToLinkFiles(ExtractLib(inppu^.getstring));
+        if not inppu^.endofentry then
+         begin
+           repeat
+             inppu^.getdatabuf(buffer^,bufsize,l);
+             outppu^.putdata(buffer^,l);
+           until l<bufsize;
+           outppu^.writeentry(b);
+         end;
+       end; }
+  end;
+{ just add a new entry with the new lib }
+  if MakeStatic then
+   begin
+     outppu^.putstring(outputfileforlink);
+     outppu^.putlongint(link_static);
+     outppu^.writeentry(iblinkunitstaticlibs)
+   end
+  else
+   begin
+     outppu^.putstring(outputfileforlink);
+     outppu^.putlongint(link_shared);
+     outppu^.writeentry(iblinkunitsharedlibs);
+   end;
+{ read all entries until the end and write them also to the new ppu }
+  repeat
+    b:=inppu^.readentry;
+  { don't write ibend, that's written automaticly }
+    if b<>ibend then
+     begin
+       repeat
+         inppu^.getdatabuf(buffer^,bufsize,l);
+         outppu^.putdata(buffer^,l);
+       until l<bufsize;
+       outppu^.writeentry(b);
+     end;
+  until b=ibend;
+{ write the last stuff and close }
+  outppu^.flush;
+  outppu^.writeheader;
+  dispose(outppu,done);
+  dispose(inppu,done);
+{ rename }
+  if PPUFn=PPLFn then
+   begin
+     {$I-}
+      assign(f,PPUFn);
+      erase(f);
+      assign(f,'ppumove.$$$');
+      rename(f,PPUFn);
+     {$I+}
+     if ioresult<>0 then;
+   end;
+{ the end }
+  If Not Quiet then
+   Writeln (' Done.');
+  DoPPU:=True;
+end;
+
+
+Function DoFile(const FileName:String):Boolean;
+{
+  Process a file, mainly here for wildcard support under Dos
+}
+{$ifndef unix}
+var
+  dir : searchrec;
+{$endif}
+begin
+{$ifdef unix}
+  DoFile:=DoPPU(FileName,ForceExtension(FileName,PPLExt));
+{$else}
+  DoFile:=false;
+  findfirst(filename,$20,dir);
+  while doserror=0 do
+   begin
+     if not DoPPU(Dir.Name,ForceExtension(Dir.Name,PPLExt)) then
+      exit;
+     findnext(dir);
+   end;
+  findclose(dir);
+  DoFile:=true;
+{$endif}
+end;
+
+
+Procedure DoLink;
+{
+  Link the object files together to form a (shared) library, the only
+  problem here is the 255 char limit of Names
+}
+Var
+  Names : String;
+  f     : file;
+  Err   : boolean;
+  P     : PLinkOEnt;
+begin
+  if not Quiet then
+   Write ('Linking ');
+  P:=ObjFiles;
+  names:='';
+  While p<>nil do
+   begin
+     if Names<>'' then
+      Names:=Names+' '+P^.name
+     else
+      Names:=p^.Name;
+     p:=p^.next;
+   end;
+  if Names='' then
+   begin
+     If not Quiet then
+      Writeln('Error: no files found to be linked');
+     exit;
+   end;
+  If not Quiet then
+   WriteLn(names);
+{ Run ar or ld to create the lib }
+  If MakeStatic then
+   Err:=Shell(arbin+' rs '+outputfile+' '+names)<>0
+  else
+   begin
+     Err:=Shell(ldbin+' -shared -o '+OutputFile+' '+names)<>0;
+     if not Err then
+      Shell(stripbin+' --strip-unneeded '+OutputFile);
+   end;
+  If Err then
+   Error('Fatal: Library building stage failed.',true);
+{ fix permission to 644, so it's not 755 }
+{$ifdef unix}
+  ChMod(OutputFile,420);
+{$endif}
+{ Rename to the destpath }
+  if DestPath<>'' then
+   begin
+     Assign(F, OutputFile);
+     Rename(F,DestPath+'/'+OutputFile);
+   end;
+end;
+
+
+Procedure usage;
+{
+  Print usage and exit.
+}
+begin
+  Writeln(paramstr(0),': [-qhwvbs] [-e ext] [-o name] [-d path] file [file ...]');
+  Halt(0);
+end;
+
+
+
+Procedure processopts;
+{
+  Process command line opions, and checks if command line options OK.
+}
+var
+  C : char;
+begin
+  if paramcount=0 then
+   usage;
+{ Reset }
+  ObjFiles:=Nil;
+  Quiet:=False;
+  Batch:=False;
+  OutputFile:='';
+  PPLExt:='ppu';
+  ArBin:='ar';
+  LdBin:='ld';
+  StripBin:='strip';
+  repeat
+    c:=Getopt (ShortOpts);
+    Case C of
+      EndOfOptions : break;
+      's' : MakeStatic:=True;
+      'o' : OutputFile:=OptArg;
+      'd' : DestPath:=OptArg;
+      'e' : PPLext:=OptArg;
+      'q' : Quiet:=True;
+      'w' : begin
+              ArBin:='arw';
+              LdBin:='ldw';
+            end;
+      'b' : Batch:=true;
+      '?' : Usage;
+      'h' : Usage;
+    end;
+  until false;
+{ Test filenames on the commandline }
+  if (OptInd>Paramcount) then
+   Error('Error: no input files',true);
+  if (OptInd<ParamCount) and (OutputFile='') then
+   Error('Error: when moving multiple units, specify an output name.',true);
+{ alloc a buffer }
+  GetMem (Buffer,Bufsize);
+  If Buffer=Nil then
+   Error('Error: could not allocate memory for buffer.',true);
+end;
+
+
+var
+  i : longint;
+begin
+  ProcessOpts;
+{ Write Header }
+  if not Quiet then
+   begin
+     Writeln(Title+' '+Version);
+     Writeln(Copyright);
+     Writeln;
+   end;
+{ Check if shared is allowed }
+{$ifndef unix}
+  if arbin<>'arw' then
+   begin
+     Writeln('Warning: shared library not supported for Go32, switching to static library');
+     MakeStatic:=true;
+   end;
+{$endif}
+{ fix the libext and outputfilename }
+  if Makestatic then
+   LibExt:=StaticLibExt
+  else
+   LibExt:=SharedLibExt;
+  if OutputFile='' then
+   OutPutFile:=Paramstr(OptInd);
+{ fix filename }
+{$ifdef unix}
+  if Copy(OutputFile,1,3)<>'lib' then
+   OutputFile:='lib'+OutputFile;
+  { For unix skip replacing the extension if a full .so.X.X if specified }
+  i:=pos('.so.',Outputfile);
+  if i<>0 then
+   OutputFileForLink:=Copy(Outputfile,4,i-4)
+  else
+   begin
+     OutputFile:=ForceExtension(OutputFile,LibExt);
+     OutputFileForLink:=Copy(Outputfile,4,length(Outputfile)-length(LibExt)-4);
+   end;
+{$else}
+  OutputFile:=ForceExtension(OutputFile,LibExt);
+  OutputFileForLink:=OutputFile;
+{$endif}
+{ Open BatchFile }
+  if Batch then
+   begin
+     Assign(BatchFile,'pmove'+BatchExt);
+     Rewrite(BatchFile);
+   end;
+{ Process Files }
+  i:=OptInd;
+  While (i<=ParamCount) and Dofile(AddExtension(Paramstr(i),PPUExt)) do
+   Inc(i);
+{ Do Linking stage }
+  DoLink;
+{ Close BatchFile }
+  if Batch then
+   begin
+     if Not Quiet then
+      Writeln('Writing pmove'+BatchExt);
+     Close(BatchFile);
+{$ifdef unix}
+     ChMod('pmove'+BatchExt,493);
+{$endif}
+   end;
+{ The End }
+  if Not Quiet then
+   Writeln('Done.');
+end.
+{
+  $Log$
+  Revision 1.1  2001-04-25 22:40:07  peter
+    * compiler dependent utils in utils/ subdir
+
+  Revision 1.2  2001/01/29 21:48:26  peter
+    * linux -> unix
+
+  Revision 1.1  2000/07/13 10:16:22  michael
+  + Initial import
+
+  Revision 1.11  2000/07/04 19:05:54  peter
+    * be optimistic: version 1.00 for some utils
+
+  Revision 1.10  2000/05/17 18:30:57  peter
+    * libname fixes for unix
+
+  Revision 1.9  2000/02/09 16:44:15  peter
+    * log truncated
+
+  Revision 1.8  2000/01/07 16:46:04  daniel
+    * copyright 2000
+
+  Revision 1.7  1999/11/25 00:00:39  peter
+    * strip created .so file with strip --strip-unneeded
+
+  Revision 1.6  1999/11/23 09:44:15  peter
+    * updated
+
+  Revision 1.5  1999/07/29 01:40:21  peter
+    * fsplit var type fixes
+
+  Revision 1.4  1999/07/28 16:53:58  peter
+    * updated for new linking, but still doesn't work because ld-unix.so.2
+      requires some more crt*.o files
+
+}