Browse Source

+ Added fpcres

git-svn-id: trunk@954 -
michael 20 years ago
parent
commit
d570eabe53

+ 7 - 0
.gitattributes

@@ -6271,6 +6271,13 @@ utils/fpcm/fpcmpkg.pp svneol=native#text/plain
 utils/fpcm/fpcmwr.pp svneol=native#text/plain
 utils/fpcm/makefile.exm -text
 utils/fpcm/readme.txt svneol=native#text/plain
+utils/fpcres/Makefile svneol=native#text/plain
+utils/fpcres/Makefile.fpc svneol=native#text/plain
+utils/fpcres/elfbfd.pas svneol=native#text/plain
+utils/fpcres/elfres.pas svneol=native#text/plain
+utils/fpcres/elfresfix.pas svneol=native#text/plain
+utils/fpcres/fpcres.lpi svneol=native#text/plain
+utils/fpcres/fpcres.pas svneol=native#text/plain
 utils/fpdoc/COPYING -text
 utils/fpdoc/Makefile svneol=native#text/plain
 utils/fpdoc/Makefile.fpc svneol=native#text/plain

+ 60 - 93
utils/Makefile

@@ -1,8 +1,8 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2005/08/10]
+# Don't edit, this file is generated by FPCMake Version 1.9.8 [2005/04/10]
 #
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-emx i386-watcom i386-netwlibc i386-wince m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos powerpc-linux powerpc-netbsd powerpc-macos powerpc-darwin powerpc-morphos sparc-linux sparc-netbsd sparc-solaris x86_64-linux x86_64-freebsd x86_64-win64 arm-linux arm-wince
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-emx i386-watcom i386-netwlibc m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos powerpc-linux powerpc-netbsd powerpc-macos powerpc-darwin powerpc-morphos sparc-linux sparc-netbsd sparc-solaris x86_64-linux x86_64-freebsd arm-linux
 BSDs = freebsd netbsd openbsd darwin
 UNIXs = linux $(BSDs) solaris qnx
 LIMIT83fs = go32v2 os2 emx watcom
@@ -233,7 +233,7 @@ PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/ext
 override PACKAGE_NAME=utils
 override PACKAGE_VERSION=2.0.0
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
+override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
@@ -277,11 +277,8 @@ endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
 endif
-ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
-endif
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
+override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
@@ -302,7 +299,7 @@ ifeq ($(FULL_TARGET),m68k-palmos)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
+override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
@@ -317,7 +314,7 @@ ifeq ($(FULL_TARGET),powerpc-morphos)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
+override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
@@ -326,19 +323,13 @@ ifeq ($(FULL_TARGET),sparc-solaris)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
+override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
 endif
-ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
-endif
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
-endif
-ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc
+override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
@@ -385,9 +376,6 @@ endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
 endif
-ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
-endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
 endif
@@ -439,15 +427,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
 endif
-ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
-endif
 ifeq ($(FULL_TARGET),arm-linux)
 override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
 endif
-ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32
-endif
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_RSTS+=rstconv
 endif
@@ -493,9 +475,6 @@ endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 override TARGET_RSTS+=rstconv
 endif
-ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_RSTS+=rstconv
-endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_RSTS+=rstconv
 endif
@@ -547,15 +526,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override TARGET_RSTS+=rstconv
 endif
-ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_RSTS+=rstconv
-endif
 ifeq ($(FULL_TARGET),arm-linux)
 override TARGET_RSTS+=rstconv
 endif
-ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_RSTS+=rstconv
-endif
 ifeq ($(FULL_TARGET),i386-linux)
 override CLEAN_UNITS+=ptopu
 endif
@@ -601,9 +574,6 @@ endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 override CLEAN_UNITS+=ptopu
 endif
-ifeq ($(FULL_TARGET),i386-wince)
-override CLEAN_UNITS+=ptopu
-endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override CLEAN_UNITS+=ptopu
 endif
@@ -655,15 +625,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override CLEAN_UNITS+=ptopu
 endif
-ifeq ($(FULL_TARGET),x86_64-win64)
-override CLEAN_UNITS+=ptopu
-endif
 ifeq ($(FULL_TARGET),arm-linux)
 override CLEAN_UNITS+=ptopu
 endif
-ifeq ($(FULL_TARGET),arm-wince)
-override CLEAN_UNITS+=ptopu
-endif
 override INSTALL_FPCPACKAGE=y
 ifdef REQUIRE_UNITSDIR
 override UNITSDIR+=$(REQUIRE_UNITSDIR)
@@ -1562,14 +1526,6 @@ REQUIRE_PACKAGES_PASJPEG=1
 REQUIRE_PACKAGES_NETDB=1
 REQUIRE_PACKAGES_LIBASYNC=1
 endif
-ifeq ($(FULL_TARGET),i386-wince)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_PASZLIB=1
-REQUIRE_PACKAGES_FCL=1
-REQUIRE_PACKAGES_PASJPEG=1
-REQUIRE_PACKAGES_NETDB=1
-REQUIRE_PACKAGES_LIBASYNC=1
-endif
 ifeq ($(FULL_TARGET),m68k-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_PASZLIB=1
@@ -1757,14 +1713,6 @@ REQUIRE_PACKAGES_POSTGRES=1
 REQUIRE_PACKAGES_MYSQL=1
 REQUIRE_PACKAGES_SQLITE=1
 endif
-ifeq ($(FULL_TARGET),x86_64-win64)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_PASZLIB=1
-REQUIRE_PACKAGES_FCL=1
-REQUIRE_PACKAGES_PASJPEG=1
-REQUIRE_PACKAGES_NETDB=1
-REQUIRE_PACKAGES_LIBASYNC=1
-endif
 ifeq ($(FULL_TARGET),arm-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_PASZLIB=1
@@ -1778,14 +1726,6 @@ REQUIRE_PACKAGES_POSTGRES=1
 REQUIRE_PACKAGES_MYSQL=1
 REQUIRE_PACKAGES_SQLITE=1
 endif
-ifeq ($(FULL_TARGET),arm-wince)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_PASZLIB=1
-REQUIRE_PACKAGES_FCL=1
-REQUIRE_PACKAGES_PASJPEG=1
-REQUIRE_PACKAGES_NETDB=1
-REQUIRE_PACKAGES_LIBASYNC=1
-endif
 ifdef REQUIRE_PACKAGES_RTL
 PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_RTL),)
@@ -2121,7 +2061,7 @@ else
 FPCCPUOPT:=
 endif
 endif
-override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPT+=-Xs $(FPCCPUOPT) -n
 override FPCOPTDEF+=RELEASE
 endif
 ifdef STRIP
@@ -2601,6 +2541,7 @@ TARGET_DIRS_H2PAS=1
 TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
+TARGET_DIRS_FPCRES=1
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 TARGET_DIRS_FPCM=1
@@ -2715,14 +2656,6 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 endif
-ifeq ($(FULL_TARGET),i386-wince)
-TARGET_DIRS_FPCM=1
-TARGET_DIRS_TPLY=1
-TARGET_DIRS_H2PAS=1
-TARGET_DIRS_FPRCP=1
-TARGET_DIRS_DXEGEN=1
-TARGET_DIRS_FPDOC=1
-endif
 ifeq ($(FULL_TARGET),m68k-linux)
 TARGET_DIRS_FPCM=1
 TARGET_DIRS_TPLY=1
@@ -2730,6 +2663,7 @@ TARGET_DIRS_H2PAS=1
 TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
+TARGET_DIRS_FPCRES=1
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 TARGET_DIRS_FPCM=1
@@ -2786,6 +2720,7 @@ TARGET_DIRS_H2PAS=1
 TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
+TARGET_DIRS_FPCRES=1
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 TARGET_DIRS_FPCM=1
@@ -2826,6 +2761,7 @@ TARGET_DIRS_H2PAS=1
 TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
+TARGET_DIRS_FPCRES=1
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 TARGET_DIRS_FPCM=1
@@ -2850,6 +2786,7 @@ TARGET_DIRS_H2PAS=1
 TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
+TARGET_DIRS_FPCRES=1
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 TARGET_DIRS_FPCM=1
@@ -2859,14 +2796,6 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 endif
-ifeq ($(FULL_TARGET),x86_64-win64)
-TARGET_DIRS_FPCM=1
-TARGET_DIRS_TPLY=1
-TARGET_DIRS_H2PAS=1
-TARGET_DIRS_FPRCP=1
-TARGET_DIRS_DXEGEN=1
-TARGET_DIRS_FPDOC=1
-endif
 ifeq ($(FULL_TARGET),arm-linux)
 TARGET_DIRS_FPCM=1
 TARGET_DIRS_TPLY=1
@@ -2874,14 +2803,7 @@ TARGET_DIRS_H2PAS=1
 TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
-endif
-ifeq ($(FULL_TARGET),arm-wince)
-TARGET_DIRS_FPCM=1
-TARGET_DIRS_TPLY=1
-TARGET_DIRS_H2PAS=1
-TARGET_DIRS_FPRCP=1
-TARGET_DIRS_DXEGEN=1
-TARGET_DIRS_FPDOC=1
+TARGET_DIRS_FPCRES=1
 endif
 ifdef TARGET_DIRS_FPCM
 fpcm_all:
@@ -3153,6 +3075,51 @@ fpdoc:
 	$(MAKE) -C fpdoc all
 .PHONY: fpdoc_all fpdoc_debug fpdoc_smart fpdoc_release fpdoc_units fpdoc_examples fpdoc_shared fpdoc_install fpdoc_sourceinstall fpdoc_exampleinstall fpdoc_distinstall fpdoc_zipinstall fpdoc_zipsourceinstall fpdoc_zipexampleinstall fpdoc_zipdistinstall fpdoc_clean fpdoc_distclean fpdoc_cleanall fpdoc_info fpdoc_makefiles fpdoc
 endif
+ifdef TARGET_DIRS_FPCRES
+fpcres_all:
+	$(MAKE) -C fpcres all
+fpcres_debug:
+	$(MAKE) -C fpcres debug
+fpcres_smart:
+	$(MAKE) -C fpcres smart
+fpcres_release:
+	$(MAKE) -C fpcres release
+fpcres_units:
+	$(MAKE) -C fpcres units
+fpcres_examples:
+	$(MAKE) -C fpcres examples
+fpcres_shared:
+	$(MAKE) -C fpcres shared
+fpcres_install:
+	$(MAKE) -C fpcres install
+fpcres_sourceinstall:
+	$(MAKE) -C fpcres sourceinstall
+fpcres_exampleinstall:
+	$(MAKE) -C fpcres exampleinstall
+fpcres_distinstall:
+	$(MAKE) -C fpcres distinstall
+fpcres_zipinstall:
+	$(MAKE) -C fpcres zipinstall
+fpcres_zipsourceinstall:
+	$(MAKE) -C fpcres zipsourceinstall
+fpcres_zipexampleinstall:
+	$(MAKE) -C fpcres zipexampleinstall
+fpcres_zipdistinstall:
+	$(MAKE) -C fpcres zipdistinstall
+fpcres_clean:
+	$(MAKE) -C fpcres clean
+fpcres_distclean:
+	$(MAKE) -C fpcres distclean
+fpcres_cleanall:
+	$(MAKE) -C fpcres cleanall
+fpcres_info:
+	$(MAKE) -C fpcres info
+fpcres_makefiles:
+	$(MAKE) -C fpcres makefiles
+fpcres:
+	$(MAKE) -C fpcres all
+.PHONY: fpcres_all fpcres_debug fpcres_smart fpcres_release fpcres_units fpcres_examples fpcres_shared fpcres_install fpcres_sourceinstall fpcres_exampleinstall fpcres_distinstall fpcres_zipinstall fpcres_zipsourceinstall fpcres_zipexampleinstall fpcres_zipdistinstall fpcres_clean fpcres_distclean fpcres_cleanall fpcres_info fpcres_makefiles fpcres
+endif
 ifdef TARGET_DIRS_FPMC
 fpmc_all:
 	$(MAKE) -C fpmc all

+ 1 - 0
utils/Makefile.fpc

@@ -10,6 +10,7 @@ version=2.0.0
 dirs=fpcm tply h2pas fprcp dxegen fpdoc
 programs=ppdep ptop rstconv data2inc delp bin2obj postw32
 dirs_win32=fpmc
+dirs_linux=fpcres
 rsts=rstconv
 
 [require]

+ 1519 - 0
utils/fpcres/Makefile

@@ -0,0 +1,1519 @@
+#
+# Don't edit, this file is generated by FPCMake Version 1.9.8 [2005/04/10]
+#
+default: all
+MAKEFILETARGETS=i386-linux m68k-linux powerpc-linux sparc-linux x86_64-linux arm-linux
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx
+LIMIT83fs = go32v2 os2 emx watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+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 cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(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
+export ECHO
+endif
+override DEFAULT_FPCDIR=../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+FPC:=$(shell $(FPCPROG) -PB)
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifneq ($(words $(FPC_COMPILERINFO)),5)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSO)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTO)
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl 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:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_PROGRAMS+=fpcres
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_PROGRAMS+=fpcres
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_PROGRAMS+=fpcres
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_PROGRAMS+=fpcres
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_PROGRAMS+=fpcres
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_PROGRAMS+=fpcres
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_RSTS+=fpcres fpcresfix elfres
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_RSTS+=fpcres fpcresfix elfres
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_RSTS+=fpcres fpcresfix elfres
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_RSTS+=fpcres fpcresfix elfres
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_RSTS+=fpcres fpcresfix elfres
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_RSTS+=fpcres fpcresfix elfres
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override CLEAN_UNITS+=fpcresfix elfbfd elfres
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override CLEAN_UNITS+=fpcresfix elfbfd elfres
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override CLEAN_UNITS+=fpcresfix elfbfd elfres
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override CLEAN_UNITS+=fpcresfix elfbfd elfres
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override CLEAN_UNITS+=fpcresfix elfbfd elfres
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override CLEAN_UNITS+=fpcresfix elfbfd elfres
+endif
+override INSTALL_FPCPACKAGE=y
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+STATICLIBPREFIX=libp
+RSTEXT=.rst
+ifeq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+ifeq ($(OS_TARGET),darwin)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+endif
+else
+ifeq ($(OS_TARGET),go32v1)
+PPUEXT=.pp1
+OEXT=.o1
+ASMEXT=.s1
+SMARTEXT=.sl1
+STATICLIBEXT=.a1
+SHAREDLIBEXT=.so1
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+PPUEXT=.ppw
+OEXT=.ow
+ASMEXT=.sw
+SMARTEXT=.slw
+STATICLIBEXT=.aw
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+PPUEXT=.ppo
+ASMEXT=.so2
+OEXT=.oo2
+AOUTEXT=.out
+SMARTEXT=.sl2
+STATICLIBPREFIX=
+STATICLIBEXT=.ao2
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+PPUEXT=.ppu
+ASMEXT=.asm
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),atari)
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifneq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),win32)
+ifeq ($(CROSSBINDIR),)
+ASNAME=asw
+LDNAME=ldw
+ARNAME=arw
+endif
+endif
+endif
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+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
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl rtl
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_RTL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(CPU_TARGET)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX) -Xc
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+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
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+else
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1
+else
+FPCCPUOPT:=
+endif
+endif
+override FPCOPT+=-Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+ifeq ($(CPU_TARGET),i386)
+override FPCOPT+=-OG2p3
+endif
+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 CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+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_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifeq ($(OS_TARGET),linux)
+ifeq ($(FPC_VERSION),1.0.6)
+override FPCOPTDEF+=HASUNIX
+endif
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+EXECPPAS:=@$(PPAS)
+endif
+endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+	@$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+	$(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+	$(MAKE) all DEBUG=1
+fpc_release:
+	$(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+	$(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+	$(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(PPUEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.lpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.dpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%.res: %.rc
+	windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+	$(MKDIR) $(INSTALL_BINDIR)
+ifdef UPXPROG
+	-$(UPXPROG) $(INSTALLEXEFILES)
+endif
+	$(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+	$(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+	$(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+	$(MKDIR) $(INSTALL_LIBDIR)
+	$(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+	ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+	$(MKDIR) $(INSTALL_DATADIR)
+	$(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+	$(MKDIR) $(INSTALL_SOURCEDIR)
+	$(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+	$(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+	$(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(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) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+	-$(DELTREE) units
+	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+	-$(DEL) *.o *.ppu *.a
+endif
+	-$(DELTREE) *$(SMARTEXT)
+	-$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+	-$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+	-$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+	@$(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)  Full Source.. $(FULL_SOURCE)
+	@$(ECHO)  Full Target.. $(FULL_TARGET)
+	@$(ECHO)  SourceSuffix. $(SOURCESUFFIX)
+	@$(ECHO)  TargetSuffix. $(TARGETSUFFIX)
+	@$(ECHO)
+	@$(ECHO)  == Directory info ==
+	@$(ECHO)
+	@$(ECHO)  Required pkgs... $(REQUIRE_PACKAGES)
+	@$(ECHO)
+	@$(ECHO)  Basedir......... $(BASEDIR)
+	@$(ECHO)  FPCDir.......... $(FPCDIR)
+	@$(ECHO)  CrossBinDir..... $(CROSSBINDIR)
+	@$(ECHO)  UnitsDir........ $(UNITSDIR)
+	@$(ECHO)  PackagesDir..... $(PACKAGESDIR)
+	@$(ECHO)
+	@$(ECHO)  GCC library..... $(GCCLIBDIR)
+	@$(ECHO)  Other library... $(OTHERLIBDIR)
+	@$(ECHO)
+	@$(ECHO)  == Tools info ==
+	@$(ECHO)
+	@$(ECHO)  As........ $(AS)
+	@$(ECHO)  Ld........ $(LD)
+	@$(ECHO)  Ar........ $(AR)
+	@$(ECHO)  Rc........ $(RC)
+	@$(ECHO)
+	@$(ECHO)  Mv........ $(MVPROG)
+	@$(ECHO)  Cp........ $(CPPROG)
+	@$(ECHO)  Rm........ $(RMPROG)
+	@$(ECHO)  GInstall.. $(GINSTALL)
+	@$(ECHO)  Echo...... $(ECHO)
+	@$(ECHO)  Shell..... $(SHELL)
+	@$(ECHO)  Date...... $(DATE)
+	@$(ECHO)  FPCMake... $(FPCMAKE)
+	@$(ECHO)  PPUMove... $(PPUMOVE)
+	@$(ECHO)  Upx....... $(UPXPROG)
+	@$(ECHO)  Zip....... $(ZIPPROG)
+	@$(ECHO)
+	@$(ECHO)  == Object info ==
+	@$(ECHO)
+	@$(ECHO)  Target Loaders........ $(TARGET_LOADERS)
+	@$(ECHO)  Target Units.......... $(TARGET_UNITS)
+	@$(ECHO)  Target Implicit Units. $(TARGET_IMPLICITUNITS)
+	@$(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)  ZipName.............. $(ZIPNAME)
+	@$(ECHO)  ZipPrefix............ $(ZIPPREFIX)
+	@$(ECHO)  ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+	@$(ECHO)  ZipSuffix............ $(ZIPSUFFIX)
+	@$(ECHO)  FullZipName.......... $(FULLZIPNAME)
+	@$(ECHO)  Install FPC Package.. $(INSTALL_FPCPACKAGE)
+	@$(ECHO)
+	@$(ECHO)  Install base dir..... $(INSTALL_BASEDIR)
+	@$(ECHO)  Install binary dir... $(INSTALL_BINDIR)
+	@$(ECHO)  Install library dir.. $(INSTALL_LIBDIR)
+	@$(ECHO)  Install units dir.... $(INSTALL_UNITDIR)
+	@$(ECHO)  Install source dir... $(INSTALL_SOURCEDIR)
+	@$(ECHO)  Install doc dir...... $(INSTALL_DOCDIR)
+	@$(ECHO)  Install example dir.. $(INSTALL_EXAMPLEDIR)
+	@$(ECHO)  Install data dir..... $(INSTALL_DATADIR)
+	@$(ECHO)
+	@$(ECHO)  Dist destination dir. $(DIST_DESTDIR)
+	@$(ECHO)  Dist zip name........ $(DIST_ZIPNAME)
+	@$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+	fpc_makefile_dirs
+fpc_makefile:
+	$(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared:
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall:
+zipinstall:
+zipsourceinstall:
+zipexampleinstall:
+zipdistinstall:
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+fpcmake$(EXEEXT): fpcresfix.pas elfbfd.pas elfres.pas fpcres.pas

+ 22 - 0
utils/fpcres/Makefile.fpc

@@ -0,0 +1,22 @@
+#
+#   Makefile.fpc for FPCMake
+#
+
+[target]
+programs=fpcres
+rsts=fpcres fpcresfix elfres
+
+[clean]
+units=fpcresfix elfbfd elfres
+
+[require]
+packages=rtl
+
+[install]
+fpcpackage=y
+
+[default]
+fpcdir=../..
+
+[rules]
+fpcmake$(EXEEXT): fpcresfix.pas elfbfd.pas elfres.pas fpcres.pas

+ 150 - 0
utils/fpcres/elfbfd.pas

@@ -0,0 +1,150 @@
+{$ifdef fpc}
+{$mode objfpc}
+{$endif}
+{$H+}
+unit elfbfd;
+
+{ELF Binary Format Description. 32/64 bit definitions }
+
+interface
+
+const
+  SHT_NULL     = 0;
+  SHT_PROGBITS = 1;
+  SHT_SYMTAB   = 2;
+  SHT_STRTAB   = 3;
+  SHT_RELA     = 4;
+  SHT_HASH     = 5;
+  SHT_DYNAMIC  = 6;
+  SHT_NOTE     = 7;
+  SHT_NOBITS   = 8;
+  SHT_REL      = 9;
+  SHT_SHLIB    = 10;
+  SHT_DYNSYM   = 11;
+  SHF_WRITE     = 1;
+  SHF_ALLOC     = 2;
+  SHF_EXECINSTR = 4;
+
+  PT_NULL       = 0;
+  PT_LOAD 	= 1;
+  PT_DYNAMIC 	= 2;
+  PT_INTERP 	= 3;
+  PT_NOTE 	= 4;
+  PT_SHLIB 	= 5;
+  PT_PHDR 	= 6;
+  PT_LOOS 	= $60000000;
+  PT_HIOS 	= $6fffffff;
+  PT_LOPROC 	= $70000000;
+  PT_HIPROC 	= $7fffffff;
+
+Type
+  TElf32header = packed record
+    magic0123: longint;
+    file_class: byte;
+    data_encoding: byte;
+    file_version: byte;
+    padding: array[$07..$0F] of byte;
+    e_type: word;
+    e_machine: word;
+    e_version: longint;
+    e_entry: longint; { entrypoint }
+    e_phoff: longint; { program header offset }
+    e_shoff: longint; { sections header offset }
+    e_flags: longint;
+    e_ehsize: word; { elf header size in bytes }
+    e_phentsize: word; { size of an entry in the program header array }
+    e_phnum: word; { 0..e_phnum-1 of entrys }
+    e_shentsize: word; { size of an entry in sections header array }
+    e_shnum: word; { 0..e_shnum-1 of entrys }
+    e_shstrndx: word; { index of string section header }
+  end;
+
+  TElf64header = packed record
+    magic0123: longint;
+    file_class: byte;
+    data_encoding: byte;
+    file_version: byte;
+    padding: array[$07..$0F] of byte;
+    e_type: word;
+    e_machine: word;
+    e_version: longint;
+    e_entry: int64; { entrypoint }
+    e_phoff: int64; { program header offset }
+    e_shoff: int64; { sections header offset }
+    e_flags: longint;
+    e_ehsize: word; { elf header size in bytes }
+    e_phentsize: word; { size of an entry in the program header array }
+    e_phnum: word; { 0..e_phnum-1 of entrys }
+    e_shentsize: word; { size of an entry in sections header array }
+    e_shnum: word; { 0..e_shnum-1 of entrys }
+    e_shstrndx: word; { index of string section header }
+  end;
+
+  TElf32sechdr = packed record
+    sh_name: longint;
+    sh_type: longint;
+    sh_flags: longint;
+    sh_addr: longint;
+    sh_offset: longint;
+    sh_size: longint;
+    sh_link: longint;
+    sh_info: longint;
+    sh_addralign: longint;
+    sh_entsize: longint;
+  end;
+
+  TElf64sechdr = packed record
+    sh_name: longint;
+    sh_type: longint;
+    sh_flags: longint;
+    sh_addr: int64;
+    sh_offset: int64;
+    sh_size: int64;
+    sh_link: longint;
+    sh_info: longint;
+    sh_addralign: int64;
+    sh_entsize: int64;
+  end;
+  
+  { FPC resources }
+  
+  TELF32ResourceSectionInfo = packed record
+    ptr: longint;
+    size: longint;
+  end;
+
+  TELF64ResourceSectionInfo = packed record
+    ptr: int64;
+    size: int64;
+  end;
+
+  TELF32ResourceInfo = packed record
+    reshash: longint; // always 32bit, contains an ELF hash of the resource entries name
+    restype: longint; // always 32bit, contains the resource type ID compatible with Windows RES IDs
+    ptr:     longint; // Byte offset to the resource inside the resdata section.
+    name:    longint; // Byte offset to the the resource name inside the ressym section.
+    size:    longint; // The size of the resource entry
+  end;
+
+  TELF64ResourceInfo = packed record
+    reshash: longint; // always 32bit, contains an ELF hash of the resource entries name
+    restype: longint; // always 32bit, contains the resource type ID compatible with Windows RES IDs
+    ptr:     int64;   // Byte offset to the resource inside the resdata section.
+    name:    int64;   // Byte offset to the the resource name inside the ressym section.
+    size:    int64;   // The size of the resource entry
+  end;
+
+  TELF32ResourceSectionTable = packed record
+    version: integer;
+    resentries: integer;
+    ressym: TELF32ResourceSectionInfo;
+    reshash: TELF32ResourceSectionInfo;
+    resdata: TELF32ResourceSectionInfo;
+    resspare: TELF32ResourceSectionInfo;
+    resstr: TELF32ResourceSectionInfo;
+  end;
+
+implementation
+
+end.
+

+ 692 - 0
utils/fpcres/elfres.pas

@@ -0,0 +1,692 @@
+{ *********************************************************************** }
+{                                                                         }
+{  fpcres2elf - Free Pascal Resource to ELF object compiler               }
+{  Part of the Free Pascal and CrossFPC distributions                     }
+{                                                                         }
+{  Copyright (C) 2005 Simon Kissel                                        }
+{                                                                         }
+{  See the file COPYING.FPC, included in the FPC distribution,            }
+{  for details about the copyright.                                       }
+{                                                                         }
+{  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.                   }
+{                                                                         }
+{ *********************************************************************** }
+
+{
+This unit will compile an ELF object file out of a supplied .res resource
+file. Optionally, Delphi/Kylix dfm/xfm form files are also accepted as
+input. These will automatically be converted into resources internally.
+
+fpcres2elf builds with Delphi, Kylix and FPC.
+
+Currently this only works on 32Bit targets, but support for 64Bit targets
+is in the works. Support for big endian systems is completely missing,
+though.
+
+Format used for the various resource sections:
+
+ fpc.resptrs:   This section is contained in resptrs.o and always linked to the executable by
+                FPC. It containes an exported label fpcrespointers, which is used at runtime
+                to find the resptrs section in memory. The resptrs contains pointers to all the
+                sections and their sizes. These are updated in a post-precessing step by the
+                compiler and by the external resource embedder when applied to an ELF file.
+                This section always is 128 Bytes long and initially filled with zeros.
+                The first integer (32/64 Bit) value in this section contains the version
+                number of the resource system. Currently this value is 1.
+                The second integer (32/64 Bit) value in this section contains the number of
+                resources.
+                After this follows a version-defined number of TFPCResourceSectionInfo entries.
+ fpc.ressym:    Contains the resource names. This simply is a stream of zero-terminated strings.
+                Only textual names are supported, numeric IDs get autoconverted to #ID's.
+                The reshash table has got a byte index into ressym to quickly get that data if needed
+ fpc.reshash:   n TFPCResourceInfo records. (number of entries is defined in fpc.resptrs)
+ fpc.resdata:   Contains the plain resource data stream. A byte index into the data stream
+                is given for each resource entry in TResourceInfo
+ fpc.resspare:  An empty section which is resized to make room if the size of any of the previous
+                sections gets changed. NOT USED IN VERSION 1 (SIZE WILL BE 0)
+ fpc.resstr:    This section is completely seperated from the rest and contains a block of
+                resourcestrings in internal FPC format.
+
+resptr TFPCResourceSectionInfo list for FPC resources version 1:
+
+Index   Pointer to
+0       ressym
+1       reshash
+2       resdata
+3       resspare
+4       resstr
+5       reserved for future extension (stabs)
+6       reserved for future extension
+}
+{$ifdef fpc}
+{$mode objfpc}
+{$endif}
+{$H+}
+unit elfres;
+
+interface
+
+uses
+  elfbfd,
+  SysUtils,
+  Classes;
+
+const fpcres2elf_version=1;
+
+// Do not change the following consts, they are dummy tables to generate an .o that makes ld happy
+const shstrtab = #0+'.symtab'+#0+'.strtab'+#0+'.shstrtab'+#0+'.text'+#0+'.data'+#0+
+                 '.bss'+#0+'fpc.ressym'+#0+'fpc.resstr'+#0+'fpc.reshash'+#0+
+                 'fpc.resdata'+#0+'fpc.resspare'+#0+#0;
+      symtab =   #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$01#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$02#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$03#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$04#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$05#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$06#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$07#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$08#$00;
+      strtab =   #$00#$00; // this actually is just one byte long
+      zeros  =   #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00;
+      fake   =   'fakefakefakefakefakefakefakefake';
+
+      // header of a windows 32 bit .res file (16 bytes)
+      reshdr =   #$00#$00#$00#$00#$20#$00#$00#$00#$FF#$FF#$00#$00#$FF#$FF#$00#$00+
+                 #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00;
+
+      FilerSignature: array[1..4] of Char = 'TPF0';
+
+      SDefaultExtension = '.or';
+      
+Type
+  { TElfResCreator }
+
+  TElfResCreator = Class(TObject)
+  private
+    FDestFileName: String;
+    FExtension: string;
+    FSourceFileName: String;
+    FOverwrite: Boolean;
+    FVerbose: Boolean;
+    FVersion: Integer;
+  Protected
+    FSectionStream: TMemoryStream;
+    FDataStream: TMemoryStream;
+    FSymStream: TMemoryStream;
+    FHashStream: TMemoryStream;
+    sectionheader_ofs: integer;
+    shstrtab_ofs: integer;
+    CurrentResource:integer;
+    resheader: string;
+    Signature: byte;
+    Procedure AllocateData; virtual;
+    Procedure FreeData; virtual;
+    Procedure DoAlign(const a: integer);
+  Public
+    Constructor Create;
+    Procedure Convert(Const Source,Destination : String);
+    Procedure ConvertStreams(Source,Dest : TStream);
+    Procedure DoConvertStreams(Source,Dest : TStream); virtual;Abstract;
+    Property  Verbose : Boolean Read FVerbose Write FVerbose;
+    Property  SourceFileName : String Read FSourceFileName;
+    Property  DestFileName : String Read FDestFileName;
+    Property  Overwrite : Boolean Read FOverwrite Write FOverWrite;
+    Property  Version : Integer Read FVersion Write FVersion;
+    Property  Extension : string Read FExtension Write FExtension;
+  end;
+  
+  { TElf32ResCreator }
+
+  TElf32ResCreator = Class(TElfResCreator)
+  Private
+    ResourceEntries: array of TELF32ResourceInfo;
+  Protected
+    Procedure AllocateData; override;
+    Procedure FreeData; override;
+  public
+    procedure LoadBinaryDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
+    procedure LoadTextDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
+    procedure LoadRESEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
+    Procedure DoConvertStreams(Source,Dest : TStream); override;
+  end;
+  
+  { TElf64Creator }
+
+  TElf64ResCreator = Class(TElfResCreator)
+    Procedure DoConvertStreams(Source,Dest : TStream); override;
+  end;
+
+  EElfResError = Class(Exception);
+
+implementation
+
+resourcestring
+  SErrUnrecognizedFormat = 'Unrecognized file format for input file "%s"';
+
+Procedure DoError (Msg : String);
+
+begin
+  Raise EElfResError.Create(Msg);
+end;
+
+Procedure DoErrorFmt (Msg : String; Args : Array of const);
+
+begin
+  Raise EElfResError.CreateFmt(Msg,Args);
+end;
+
+function HashELF(const S : string) : longint;
+{Note: this hash function is described in "Practical Algorithms For
+       Programmers" by Andrew Binstock and John Rex, Addison Wesley,
+       with modifications in Dr Dobbs Journal, April 1996}
+var
+  G : longint;
+  i : integer;
+begin
+  Result := 0;
+  for i := 1 to length(S) do begin
+    Result := (Result shl 4) + ord(S[i]);
+    G := Result and $F0000000;
+    if (G <> 0) then
+      Result := Result xor (G shr 24);
+    Result := Result and (not G);
+  end;
+end;
+
+{ TElfResCreator }
+
+procedure TElfResCreator.AllocateData;
+begin
+  FSectionStream:=TMemoryStream.Create;
+  FDataStream:=TMemoryStream.Create;
+  FSymStream:=TMemoryStream.Create;
+  FHashStream:=TMemoryStream.Create;
+end;
+
+procedure TElfResCreator.FreeData;
+begin
+  FreeAndNil(FSectionStream);
+  FreeAndNil(FDataStream);
+  FreeAndNil(FSymStream);
+  FreeAndNil(FHashStream);
+end;
+
+constructor TElfResCreator.Create;
+begin
+  FVersion:=fpcres2elf_version;
+  FOverwrite:=True;
+  FVerbose:=False;
+  FExtension:=SDefaultExtension;
+end;
+
+// fill the memorystream so it is aligned, max supported align is 16
+procedure TElfResCreator.DoAlign(const a: integer);
+var i: integer;
+begin
+  i:=(4 - (FSectionStream.position MOD a)) MOD a;
+  if (i>0) then FSectionStream.Write(zeros,i);
+end;
+
+procedure TElfResCreator.Convert(const Source, Destination: String);
+
+Var
+  Src,Dest : TFileStream;
+
+begin
+  FSourceFileName:=Source;
+  FDestFileName:=Destination;
+  if FDestFileName='' then
+    FDestFileName:=ChangeFileExt(Source,FExtension);
+  Src:=TFileStream.Create(FSourceFileName,fmOpenRead or fmShareDenyWrite);
+  try
+    Dest:=TFileStream.Create(FDestFileName,fmCreate or fmShareDenyWrite);
+    Try
+      ConvertStreams(Src,Dest);
+    Finally
+      Dest.Free;
+    end;
+  Finally
+    Src.Free;
+  end;
+end;
+
+procedure TElfResCreator.ConvertStreams(Source, Dest: TStream);
+begin
+  AllocateData;
+  Try
+    DoConvertStreams(Source,Dest);
+  Finally
+    FreeData;
+  end;
+end;
+
+{ ---------------------------------------------------------------------
+  TElf32ResCreator
+  ---------------------------------------------------------------------}
+
+procedure TElf32ResCreator.AllocateData;
+begin
+  inherited AllocateData;
+  // reserve space for 1024 resource entries for now
+  SetLength(ResourceEntries,1024);
+  CurrentResource:=0;
+end;
+
+procedure TElf32ResCreator.FreeData;
+begin
+  inherited FreeData;
+  SetLength(ResourceEntries,0);
+end;
+
+procedure TElf32ResCreator.LoadRESEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
+var l:longint;
+    w:word;
+    ws:WideString;
+    wc:WideChar;
+    name:string;
+    i: integer;
+    headersize:integer;
+    headerstart:integer;
+begin
+  headerstart:=rs.Position;
+  resinfo.ptr:=DataStream.Position;
+  rs.Read(resinfo.size,4);
+  rs.Read(headersize,4);
+  rs.Read(l,4); // Type
+  if (l AND $0000FFFF)=$0000FFFF then
+  begin // Type is stored as ID
+    resinfo.restype:=(l AND $FFFF0000) shr 16; // kill the marker, we always use IDs
+  end
+  else
+  begin
+    // we don't support text IDs for now, skip until we have reached the end
+    // of the widestring, and set rcdata (10) in this case.
+    repeat
+      rs.Read(w,2);
+    until w=0;
+    resinfo.restype:=10;
+  end;
+
+  rs.Read(l,4); // Name
+  if (l AND $0000FFFF)=$0000FFFF then
+  begin // Name is stored as ID.
+    l:=(l AND $FFFF0000) shr 16; // kill the marker
+    // We don't want to support integer names, we'll instead convert them to a #id string
+    // which is more common.
+    name:='#'+inttostr(l);
+  end
+  else
+  begin
+    // Ok, it's a widestring ID
+    ws:=widechar(l AND $0000FFFF);
+    ws:=ws+widechar((l AND $FFFF0000) shr 16);
+    // get the rest of it
+    repeat
+      rs.Read(wc,2);
+      if wc<>#0 then ws:=ws+wc;
+    until wc=#0;
+    // convert to ANSI
+    name:=ws;
+  end;
+
+  // create a hash of the name
+  resinfo.reshash:=HashELF(name);
+
+  // save the name plus a trailing #0 to the SymStream, also save
+  // the position of this name in the SymStream
+  resinfo.name:=SymStream.Position;
+  name:=name+#0;
+  SymStream.Write(name[1],length(name));
+
+  // We don't care about the rest of the header
+  rs.Seek(headersize-(rs.position-headerstart),soFromCurrent);
+
+  // Now copy over the resource data into our internal memory stream
+  DataStream.CopyFrom(rs,resinfo.size);
+
+  // Align the resource stream on a dword boundary
+  i:=(4 - (rs.Position MOD 4)) MOD 4;
+  if (i>0) then rs.Seek(i,soFromCurrent);
+
+
+  // Align the data stream on a dword boundary
+  i:=(4 - (DataStream.Position MOD 4)) MOD 4;
+  if (i>0) then DataStream.Write(zeros,i);
+end;
+
+procedure TElf32ResCreator.LoadBinaryDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
+var name: string;
+    i: integer;
+begin
+  resinfo.ptr:=0;
+  resinfo.restype:=10; // RCDATA
+
+  // Skip the header
+  rs.Position:=3;
+
+  // Read the name
+  setlength(name,64); // Component names can be 64 chars at max
+  rs.Read(name[1],64);
+
+  // Find end of name
+  i:=pos(#0,name);
+  name:=copy(name,1,i-1);
+
+  // Seek to after the name and skip other crap
+  rs.Position:=i+9;
+
+  resinfo.size:=rs.Size-rs.Position;
+
+  // ...this is followed by the data.
+
+  // create a hash of the name
+  resinfo.reshash:=HashELF(name);
+
+  // save the name plus a trailing #0 to the SymStream, also save
+  // the position of this name in the SymStream
+  resinfo.name:=SymStream.Position;
+  name:=name+#0;
+  SymStream.Write(name[1],length(name));
+
+  // Now copy over the resource data into our internal memory stream
+  DataStream.CopyFrom(rs,resinfo.size);
+
+  // Align the data stream on a dword boundary
+  i:=(4 - (DataStream.Position MOD 4)) MOD 4;
+  if (i>0) then DataStream.Write(zeros,i);
+end;
+
+procedure TElf32ResCreator.LoadTextDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
+var ms:TMemoryStream;
+begin
+  ms:=nil;
+  try
+    ms:=TMemoryStream.Create;
+    ObjectTextToResource(rs,ms);
+    LoadBinaryDFMEntry(ms, DataStream, SymStream, resinfo);
+  finally
+    ms.free;
+  end;
+end;
+
+procedure TElf32ResCreator.DoConvertStreams(Source, Dest: TStream);
+
+Var
+  I : Integer;
+  ElfHeader: TElf32Header;
+  SectionHeader: TElf32sechdr;
+  ressym: TELF32ResourceSectionInfo;
+  resstr: TELF32ResourceSectionInfo;
+  reshash: TELF32ResourceSectionInfo;
+  resdata: TELF32ResourceSectionInfo;
+  resspare: TELF32ResourceSectionInfo;
+  
+begin
+  // Read and check the header of the input file. First check if it's a 32bit resource
+  // file...
+  SetLength(resheader,32);
+  Source.Read(resheader[1],32);
+  if (resheader<>reshdr) then
+    begin
+    // ...not a 32Bit resource file. Now let's see if it's a text or binary dfm/xfm/lfm file.
+    Source.Position:=0;
+    Source.Read(Signature,1);
+    if (Signature=$FF) then
+      begin
+      Source.Position:=0;
+      LoadBinaryDFMEntry(Source, FDataStream, FSymStream, ResourceEntries[CurrentResource]);
+      end
+    else if char(Signature) in ['o','O','i','I',' ',#13,#11,#9] then
+      begin
+      Source.Position:=0;
+      LoadTextDFMEntry(Source, FDataStream, FSymStream, ResourceEntries[CurrentResource]);
+      end
+    else
+      DoErrorFmt(SErrUnrecognizedFormat,[SourceFileName]);
+    inc(CurrentResource,1);
+    end
+  else // ...yes, it's a resource file.
+    while Source.Position<Source.Size do
+      begin
+      // Load Resource info, and copy the resource data into the DataStream
+      LoadRESEntry(Source, FDataStream, FSymStream, ResourceEntries[CurrentResource]);
+      inc(CurrentResource,1);
+      // if we hit the current limit of allocated ResourceEntries in the
+      // array, allocate some more space
+      if (CurrentResource>=length(ResourceEntries)) then
+        setlength(ResourceEntries,length(ResourceEntries)+1024);
+      end;
+
+  // downsize the ResourceEntries to the really needed size
+  SetLength(ResourceEntries,CurrentResource);
+
+  // Write the symbol table - ressym
+  ressym.ptr:=FSectionStream.Position+sizeof(TElf32Header);
+  FSymStream.Position:=0;
+  FSectionStream.CopyFrom(FSymStream,FSymStream.Size);
+  doalign(4);
+
+  // resstr
+  resstr.ptr:=FSectionStream.Position+sizeof(TElf32Header);
+  resstr.size:=0;
+  // TODO: Load string data here
+  doalign(4);
+
+  // Now write the ResourceInfos.
+  reshash.ptr:=FSectionStream.Position+sizeof(TElf32Header);
+  for i:=0 to high(ResourceEntries) do
+  begin
+    FSectionStream.Write(ResourceEntries[i],sizeof(TELF32ResourceInfo));
+  end;
+  doalign(4);
+
+  // Next write the resource data stream
+  resdata.ptr:=FSectionStream.Position+sizeof(TElf32Header);
+  FDataStream.Position:=0;
+  FSectionStream.CopyFrom(FDataStream,FDataStream.Size);
+  doalign(4);
+
+  // resspare
+  resspare.ptr:=FSectionStream.Position+sizeof(TElf32Header);
+  // don't write anything, this is an empty section
+
+  // shstrtab - this is not aligned
+  shstrtab_ofs:=FSectionStream.Position+sizeof(TElf32Header);
+  FSectionStream.Write(shstrtab,length(shstrtab));
+
+  // Write 12 section headers. The headers itself don't need to be aligned,
+  // as their size can be divided by 4. As shstrtab is uneven and not aligned,
+  // we however need to align the start of the section header table
+  doalign(4);
+  sectionheader_ofs:=FSectionStream.Position+sizeof(TElf32Header);;
+
+  // empty one
+  fillchar(SectionHeader,sizeof(SectionHeader),0);
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // .text
+  SectionHeader.sh_name:=$1B;
+  SectionHeader.sh_type:=1; // PROGBITS
+  SectionHeader.sh_flags:=6; // AX
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0
+  SectionHeader.sh_size:=0; // yep, pretty empty it is
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // .data
+  SectionHeader.sh_name:=$21;
+  SectionHeader.sh_type:=1; // PROGBITS
+  SectionHeader.sh_flags:=3; // WA
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0
+  SectionHeader.sh_size:=0; // yep, pretty empty it is
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // .bss
+  SectionHeader.sh_name:=$27;
+  SectionHeader.sh_type:=8; // NOBITS
+  SectionHeader.sh_flags:=3; // WA
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0
+  SectionHeader.sh_size:=0; // yep, pretty empty it is
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // fpc.ressym
+  SectionHeader.sh_name:=$2C;
+  SectionHeader.sh_type:=1; // PROGBITS
+  SectionHeader.sh_flags:=2; // A
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=ressym.ptr; // directly after header
+  SectionHeader.sh_size:=FSymStream.Size;
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // fpc.resstr
+  SectionHeader.sh_name:=$37;
+  SectionHeader.sh_type:=1; // PROGBITS
+  SectionHeader.sh_flags:=2; // A
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=resstr.ptr;
+  SectionHeader.sh_size:=0; // currently empty
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // fpc.reshash
+  SectionHeader.sh_name:=$42;
+  SectionHeader.sh_type:=1; // PROGBITS
+  SectionHeader.sh_flags:=2; // A
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=reshash.ptr;
+  SectionHeader.sh_size:=length(ResourceEntries)*sizeof(TELF32ResourceInfo)+4;
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // fpc.resdata
+  SectionHeader.sh_name:=$4e;
+  SectionHeader.sh_type:=1; // PROGBITS
+  SectionHeader.sh_flags:=2; // A
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=resdata.ptr;
+  SectionHeader.sh_size:=FDataStream.Size;
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // fpc.resspare
+  // Not used in V1
+  SectionHeader.sh_name:=$5a;
+  SectionHeader.sh_type:=8; // NOBITS
+  SectionHeader.sh_flags:=2; // A
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=resspare.ptr; // fake, as it's empty, should be equal to shstrtab's offset
+  SectionHeader.sh_size:=0; //DataStream.Size; // Leave as much room as we currently have in resdata section
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // .shstrtab
+  SectionHeader.sh_name:=$11;
+  SectionHeader.sh_type:=3; // STRTAB
+  SectionHeader.sh_flags:=0;
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=shstrtab_ofs;  // $3E
+  SectionHeader.sh_size:=$67;
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=1; // alignment
+  SectionHeader.sh_entsize:=0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // .symtab
+  SectionHeader.sh_name:=$01;
+  SectionHeader.sh_type:=2; // SYMTAB
+  SectionHeader.sh_flags:=0;
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=FSectionStream.Position+sizeof(TElf32Header)+sizeOf(SectionHeader)+sizeOf(SectionHeader); // will come directly after this and the next section. $0288;
+  SectionHeader.sh_size:=$90;
+  SectionHeader.sh_link:=$0B;
+  SectionHeader.sh_info:=$09;
+  SectionHeader.sh_addralign:=4; // alignment
+  SectionHeader.sh_entsize:=$10;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // .strtab
+  SectionHeader.sh_name:=$09;
+  SectionHeader.sh_type:=3; // STRTAB
+  SectionHeader.sh_flags:=0;
+  SectionHeader.sh_addr:=0;
+  SectionHeader.sh_offset:=FSectionStream.Position+sizeof(TElf32Header)+sizeOf(SectionHeader)+$90; // will come after this sectionheader and the $90 bytes symtab - $0318; end of file
+  SectionHeader.sh_size:=1;
+  SectionHeader.sh_link:=0;
+  SectionHeader.sh_info:=0;
+  SectionHeader.sh_addralign:=1; // alignment
+  SectionHeader.sh_entsize:=$0;
+  FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
+
+  // now write the symbol table
+  FSectionStream.Write(symtab,length(symtab));
+  // We don't need to align it, as it's $90 in size
+
+  // now write the string table, it's just a single byte
+  FSectionStream.Write(strtab,1);
+
+  // Ok, we are done, now let's really write something to disk...
+
+  // First write the ELF header
+
+  fillchar(ElfHeader,sizeof(ElfHeader),0);
+  ElfHeader.magic0123:=$464c457f; { = #127'ELF' }
+  ElfHeader.file_class:=1;
+  ElfHeader.data_encoding:=1;
+  ElfHeader.file_version:=1;
+  ElfHeader.e_type:=1;
+  ElfHeader.e_machine:=3;
+  ElfHeader.e_version:=1;
+  ElfHeader.e_shoff:=sectionheader_ofs;
+  ElfHeader.e_shstrndx:=9;
+  ElfHeader.e_shnum:=12;
+  ElfHeader.e_ehsize:=sizeof(TElf32header);
+  ElfHeader.e_shentsize:=sizeof(TElf32sechdr);
+
+  Dest.Write(ElfHeader,sizeof(TElf32header));
+
+  // And now let's dump our whole memorystream into it.
+  Dest.CopyFrom(FSectionStream,0);
+end;
+
+
+{ TElf64Creator }
+
+procedure TElf64ResCreator.DoConvertStreams(Source, Dest: TStream);
+begin
+  DoError('64 bits resources not yet supported')
+end;
+
+end.

+ 260 - 0
utils/fpcres/elfresfix.pas

@@ -0,0 +1,260 @@
+
+{ *********************************************************************** }
+{                                                                         }
+{  elfresfix - Free Pascal Resource to ELF object compiler - fixup tool   }
+{  Part of the Free Pascal and CrossFPC distributions                     }
+{                                                                         }
+{  Copyright (C) 2005 Simon Kissel                                        }
+{                                                                         }
+{  See the file COPYING.FPC, included in the FPC distribution,            }
+{  for details about the copyright.                                       }
+{                                                                         }
+{  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.                   }
+{                                                                         }
+{ *********************************************************************** }
+
+{
+This tool will update the fpc.resptrs section of an ELF executable to point
+to the various resource sections in the file. This is done so that the FPC
+RTL at runtime is able to get pointers to these sections.
+
+This tool is automatically run on any fpc compiled ELF executable that
+contains ELF resources.
+
+fpcresfix builds with Delphi, Kylix and FPC.
+
+Currently this only works on 32Bit targets, but support for 64Bit targets
+is in the works. Support for big endian systems is completely missing,
+though.
+}
+{$ifdef fpc}
+{$mode objfpc}
+{$endif}
+{$h+}
+
+unit elfresfix;
+
+interface
+
+uses
+  SysUtils, Classes, elfbfd;
+  
+Type
+
+  TLogEvent = Procedure(Const Msg : String) of object;
+  
+  { TElfResourceFixer }
+
+  TElfResourceFixer = Class(TObject)
+  private
+    FFileName: String;
+    FOnVerbose: TLogEvent;
+    FVerbose: Boolean;
+    Procedure DoVerbose(Msg : String);
+  public
+    Procedure FixFile(AFileName : String);
+    Procedure DoFixStream(Stream : TStream); virtual; abstract;
+    Property Verbose : Boolean read FVerbose write FVerbose;
+    Property FileName : String Read FFileName;
+    Property Onverbose : TLogEvent Read FOnVerbose Write FOnVerbose;
+  end;
+  
+  { TElf32ResourceFixer }
+
+  TElf32ResourceFixer = Class(TElfResourceFixer)
+    Procedure DoFixStream(Stream : TStream); override;
+  end;
+  
+  { TElf64ResourceFixer }
+
+  TElf64ResourceFixer = Class(TElfResourceFixer)
+    Procedure DoFixStream(Stream : TStream); override;
+  end;
+
+  EElfResFixError = Class(Exception);
+
+Implementation
+
+ResourceString
+  SCheckingHeader           = 'Checking ELF Header... ';
+  SReadingSectionHeaders    = 'Reading Section Headers...';
+  SHeaderOK                 = 'ELF Header is OK';
+  SCheckingHeaderTable      = 'Checking Section Header table...';
+  SStrTabFound              = 'Found strtab...';
+  SProcessingSection        = 'Processing section: ';
+  SUpdatingResptrs          = 'Updating resptrs section...';
+  SFileFixed                = 'File fixed successfully!';
+  SNothingToFix             = 'There was nothing to fix in this file.';
+  
+  SErrUnsupportedHeaderSize = 'Unsupported Section Header size.';
+  SErrInvalidELFHeader      = 'Not a valid linux ELF binary.';
+  SErrResPtrsNotFound       = 'Unable to find resptrs section.';
+  
+Procedure DoError (Msg : String);
+
+begin
+  Raise EElfResFixError.Create(Msg);
+end;
+
+Procedure DoErrorFmt (Msg : String; Args : Array of const);
+
+begin
+  Raise EElfResFixError.CreateFmt(Msg,Args);
+end;
+
+{ TElfResourceFixer }
+
+procedure TElfResourceFixer.DoVerbose(Msg: String);
+begin
+  If FVerbose and Assigned(FOnVerbose) then
+    FOnVerbose(Msg);
+end;
+
+procedure TElfResourceFixer.FixFile(AFileName: String);
+
+Var
+  F : TStream;
+
+begin
+  FFileName:=AFileName;
+  F:=TFileStream.Create(AFilename,fmOpenReadWrite or fmShareDenyWrite);
+  Try
+    DoFixStream(F);
+  Finally
+    F.Free;
+  end;
+end;
+
+{ TElf32ResourceFixer }
+
+procedure TElf32ResourceFixer.DoFixStream(Stream: TStream);
+
+var
+  ElfHeader:TElf32header;
+  ResourceSectionTable: TElf32ResourceSectionTable;
+  SectionHeaders: array of TElf32sechdr;
+
+  i:integer;
+  sn:string;
+  SectionHeaderOffset:integer;
+  fixed: boolean;
+  strtab:string;
+  SectionName: string;
+  ResPtrsSection: integer;
+
+begin
+  Fixed:=False;
+  Stream.Read(ElfHeader,sizeof(TElf32header));
+  DoVerbose(SCheckingHeader);
+  if (ElfHeader.magic0123<>$464C457F) then
+    DoError(SErrInvalidELFheader);
+  if ElfHeader.e_shentsize=sizeof(TElf32sechdr) then
+    DoVerbose(SHeaderOK)
+  else
+    DoError(SErrUnSupportedHeaderSize);
+  DoVerbose(SReadingSectionHeaders);
+
+  setlength(SectionHeaders,ElfHeader.e_shnum);
+  SectionHeaderOffset:=ElfHeader.e_shoff;
+  Stream.Position:=SectionHeaderOffset;
+
+  for i:=0 to ElfHeader.e_shnum-1 do
+    begin
+    Stream.Read(SectionHeaders[i],sizeof(TElf32sechdr));
+    end;
+
+  DoVerbose(SCheckingHeaderTable);
+
+  // Get the section header strtab
+  i:=ElfHeader.e_shstrndx;
+  if SectionHeaders[i].sh_type=SHT_STRTAB then
+    begin
+    DoVerbose(SStrTabFound);
+    // read the strtab
+    Stream.Position:=SectionHeaders[i].sh_offset;
+    setlength(strtab,SectionHeaders[i].sh_size);
+    Stream.Read(strtab[1],SectionHeaders[i].sh_size);
+  end
+  else
+  begin
+    writeln('Error: Unable to find strtab.');
+    halt(5);
+  end;
+
+  ResPtrsSection:=-1;
+  ResourceSectionTable.version:=66;
+
+  // Next cycle through all sections to gather pointers to all the resource
+  // sections, and note the index of the resptrs section
+  for i:=0 to ElfHeader.e_shnum-1 do
+    begin
+    SectionName:=copy(strtab,SectionHeaders[i].sh_name+1,32);
+    SectionName:=copy(SectionName,1,pos(#0,SectionName)-1);
+    DoVerbose(SProcessingSection+SectionName);
+    sn:=Copy(SectionName,1,4);
+    // FPC section ?
+    if (sn='fpc.') then
+      begin
+      sn:=SectionName;
+      Delete(SN,1,4);
+      if SN='resptrs' then
+        begin
+        ResPtrsSection:=i;
+        end
+      else if sn='ressym' then
+        begin
+        ResourceSectionTable.ressym.ptr:=SectionHeaders[i].sh_addr;
+        ResourceSectionTable.ressym.size:=SectionHeaders[i].sh_size;
+        end
+      else if sn='reshash' then
+        begin
+        ResourceSectionTable.reshash.ptr:=SectionHeaders[i].sh_addr;
+        ResourceSectionTable.reshash.size:=SectionHeaders[i].sh_size;
+        ResourceSectionTable.resentries:=SectionHeaders[i].sh_size DIV sizeof(TELF32ResourceInfo);
+        end
+      else if sn='resdata' then
+        begin
+        ResourceSectionTable.resdata.ptr:=SectionHeaders[i].sh_addr;
+        ResourceSectionTable.resdata.size:=SectionHeaders[i].sh_size;
+        end
+      else if sn='resspare' then
+        begin
+        ResourceSectionTable.resspare.ptr:=SectionHeaders[i].sh_addr;
+        ResourceSectionTable.resspare.size:=SectionHeaders[i].sh_size;
+        end
+      else if SectionName='resstr' then
+        begin
+        ResourceSectionTable.resstr.ptr:=SectionHeaders[i].sh_addr;
+        ResourceSectionTable.resstr.size:=SectionHeaders[i].sh_size;
+        end;
+      end
+  end;
+
+  // Ok, we now have pointers to all resource sections and also
+  // know the number of resources.
+  // Now update the resptrs table
+  if ResPtrsSection>-1 then
+    begin
+    Doverbose(SUpdatingResPtrs);
+    Stream.Position:=SectionHeaders[ResPtrsSection].sh_offset;
+    Stream.Write(ResourceSectionTable,sizeof(TELF32ResourceSectionTable));
+    fixed:=true;
+    end
+  else
+    DoError(SErrREsptrsNotFound);
+  if fixed then
+    DoVerbose(SFileFixed)
+  else
+    writeln(SNothingToFix);
+end;
+
+{ TElf64ResourceFixer }
+
+procedure TElf64ResourceFixer.DoFixStream(Stream: TStream);
+begin
+  DoError('64-bit resources not yet supported');
+end;
+
+end.

+ 171 - 0
utils/fpcres/fpcres.lpi

@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <PathDelim Value="/"/>
+    <Version Value="5"/>
+    <General>
+      <Flags>
+        <MainUnitHasUsesSectionForAllUnits Value="False"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+      </Flags>
+      <MainUnit Value="0"/>
+      <ActiveEditorIndexAtStart Value="0"/>
+      <IconPath Value="./"/>
+      <TargetFileExt Value=""/>
+    </General>
+    <JumpHistory Count="18" HistoryIndex="17">
+      <Position1>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="175" Column="14" TopLine="138"/>
+      </Position1>
+      <Position2>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="144" Column="11" TopLine="122"/>
+      </Position2>
+      <Position3>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="143" Column="5" TopLine="122"/>
+      </Position3>
+      <Position4>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="148" Column="29" TopLine="126"/>
+      </Position4>
+      <Position5>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="152" Column="5" TopLine="130"/>
+      </Position5>
+      <Position6>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="162" Column="8" TopLine="140"/>
+      </Position6>
+      <Position7>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="162" Column="8" TopLine="140"/>
+      </Position7>
+      <Position8>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="163" Column="3" TopLine="141"/>
+      </Position8>
+      <Position9>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="162" Column="34" TopLine="141"/>
+      </Position9>
+      <Position10>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="170" Column="25" TopLine="148"/>
+      </Position10>
+      <Position11>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="170" Column="25" TopLine="148"/>
+      </Position11>
+      <Position12>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="170" Column="25" TopLine="148"/>
+      </Position12>
+      <Position13>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="148" Column="17" TopLine="148"/>
+      </Position13>
+      <Position14>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="67" Column="16" TopLine="67"/>
+      </Position14>
+      <Position15>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="70" Column="1" TopLine="28"/>
+      </Position15>
+      <Position16>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="233" Column="27" TopLine="190"/>
+      </Position16>
+      <Position17>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="143" Column="5" TopLine="121"/>
+      </Position17>
+      <Position18>
+        <Filename Value="fpcres.pas"/>
+        <Caret Line="137" Column="1" TopLine="137"/>
+      </Position18>
+    </JumpHistory>
+    <Units Count="5">
+      <Unit0>
+        <CursorPos X="18" Y="4"/>
+        <EditorIndex Value="0"/>
+        <Filename Value="fpcres.pas"/>
+        <IsPartOfProject Value="True"/>
+        <Loaded Value="True"/>
+        <TopLine Value="1"/>
+        <UnitName Value="fpcres"/>
+        <UsageCount Value="32"/>
+      </Unit0>
+      <Unit1>
+        <CursorPos X="1" Y="235"/>
+        <EditorIndex Value="1"/>
+        <Filename Value="elfres.pas"/>
+        <IsPartOfProject Value="True"/>
+        <Loaded Value="True"/>
+        <TopLine Value="206"/>
+        <UnitName Value="elfres"/>
+        <UsageCount Value="32"/>
+      </Unit1>
+      <Unit2>
+        <CursorPos X="1" Y="1"/>
+        <Filename Value="/home/michael/cmdline.pp"/>
+        <TopLine Value="1"/>
+        <UsageCount Value="10"/>
+      </Unit2>
+      <Unit3>
+        <CursorPos X="1" Y="1"/>
+        <EditorIndex Value="3"/>
+        <Filename Value="elfbfd.pas"/>
+        <IsPartOfProject Value="True"/>
+        <Loaded Value="True"/>
+        <TopLine Value="1"/>
+        <UnitName Value="elfbfd"/>
+        <UsageCount Value="25"/>
+      </Unit3>
+      <Unit4>
+        <CursorPos X="1" Y="121"/>
+        <EditorIndex Value="2"/>
+        <Filename Value="elfresfix.pas"/>
+        <IsPartOfProject Value="True"/>
+        <Loaded Value="True"/>
+        <TopLine Value="109"/>
+        <UnitName Value="elfresfix"/>
+        <UsageCount Value="25"/>
+      </Unit4>
+    </Units>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IgnoreBinaries Value="False"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="5"/>
+    <CodeGeneration>
+      <Generate Value="Faster"/>
+    </CodeGeneration>
+    <Other>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="2">
+      <Item1>
+        <Name Value="ECodetoolError"/>
+      </Item1>
+      <Item2>
+        <Name Value="EFOpenError"/>
+      </Item2>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 277 - 0
utils/fpcres/fpcres.pas

@@ -0,0 +1,277 @@
+{$ifdef fpc}
+{$mode objfpc}
+{$endif}
+{$apptype console}
+{$H+}
+program fpcres;
+
+uses
+  Classes, SysUtils, elfres, elfresfix;
+
+resourcestring
+  SError           = 'Error:';
+  SErrUnknownParam = 'Unknown command-line parameter : %s';
+  SErrNeedArgument = 'Option at pos %d (%s) needs an argument.';
+  SErrNoInputFile  = 'No input filename was specified';
+  SErrNoOutputFile = 'Outputfile is not allowed when multiple input files are given';
+  SErrOutputFileIllegal = 'Outputfile not allowed when fixing headers.';
+
+  SUsage010 = 'fpcres - Free Pascal Resource to ELF object compiler';
+  SUsage020 = 'Part of the Free Pascal and CrossFPC distributions';
+  SUsage030 = 'Copyright (C) 2005 Simon Kissel';
+  SUsage040 = '--------------------------------------------------------';
+  SUsage050 = 'Usage: fpcres [options] -i inputfile [-i inputfile] [-o outputfile]';
+  SUsage055 = ' where options are one or more of:';
+  SUsage060 = ' -i --input=inputfile';
+  SUsage065 = '                   A file in windows .res resource format, ';
+  SUsage070 = '                   or a Delphi/Kylix form file in dfm/xfm  ';
+  SUsage080 = '                   format (binary or text).';
+  SUSage085 = '                   More than one inputfile may be specified.';
+  SUsage090 = ' -o --output=outputfile';
+  SUsage095 = '                   Name of the object file to generate. If ';
+  SUsage100 = '                   omitted, the name of the input file will';
+  SUsage110 = '                   be used, with .or as extension.';
+  SUSage115 = '                   (not allowed with multiple input files.)';
+  SUsage116 = ' -e --extension=ext';
+  SUsage117 = '                   use ext as the extension for output filenames';
+  SUsage120 = ' -h --help         show this help message.';
+  SUsage130 = ' -f --fixheader    fix resource block header.';
+  SUsage140 = ' -6 --64bit        Use 64-bit elf resources.';
+  SUsage150 = ' -v --verbose      be verbose.';
+
+
+Type
+  TRunMode = (rmCreateElfRes,rmFixHeader);
+
+Var
+  RunMode        : TRunMode;
+  InputFiles     : TStringList;
+  OutputFileName : String;
+  Use64bit       : Boolean;
+  BeVerbose      : Boolean;
+  UseExt         : String;
+
+Procedure Usage(ExitStatus : Word);
+
+begin
+  Writeln(SUsage010);
+  Writeln(SUsage020);
+  Writeln(SUsage030);
+  Writeln(SUsage040);
+  Writeln(SUsage050);
+  Writeln(SUsage055);
+  Writeln(SUsage060);
+  Writeln(SUsage065);
+  Writeln(SUsage070);
+  Writeln(SUsage080);
+  Writeln(SUSage085);
+  Writeln(SUsage090);
+  Writeln(SUsage095);
+  Writeln(SUsage100);
+  Writeln(SUsage110);
+  Writeln(SUSage115);
+  Writeln(SUSage116);
+  Writeln(SUSage117);
+  Writeln(SUsage120);
+  Writeln(SUsage130);
+  Writeln(SUsage140);
+  Writeln(SUsage150);
+  Halt(ExitStatus);
+end;
+
+Procedure DoError(Msg : String; Args : Array of const);
+
+begin
+  Writeln(SError,' ',Format(Msg,Args));
+  Usage(1);
+end;
+
+Procedure AnalyzeParams;
+
+  Function CheckOption(Index : Integer;Short,Long : String): Boolean;
+
+  var
+    O : String;
+
+  begin
+    O:=Paramstr(Index);
+    Result:=(O='-'+short) or (copy(O,1,Length(Long)+3)=('--'+long+'='));
+  end;
+
+  Function OptionArg(Var Index : Integer) : String;
+
+  Var
+    P : Integer;
+
+  begin
+    if (Length(ParamStr(Index))>1) and (Paramstr(Index)[2]<>'-') then
+      begin
+      If Index<ParamCount then
+        begin
+        Inc(Index);
+        Result:=Paramstr(Index);
+        end
+      else
+        DoError(SErrNeedArgument,[Index,ParamStr(Index)]);
+      end
+    else If length(ParamStr(Index))>2 then
+      begin
+      P:=Pos('=',Paramstr(Index));
+      If (P=0) then
+        DoError(SErrNeedArgument,[Index,ParamStr(Index)])
+      else
+        begin
+        Result:=Paramstr(Index);
+        Delete(Result,1,P);
+        end;
+      end;
+  end;
+
+Var
+  I : Integer;
+  P : String;
+  
+begin
+  RunMode:=rmCreateElfres;
+  Use64bit:=False;
+  BeVerbose:=False;
+  I:=0;
+  While (I<ParamCount) do
+    begin
+    Inc(I);
+    // Values.
+    If Checkoption(I,'o','output') then
+      OutPutFileName:=OptionArg(I)
+    else if Checkoption(I,'i','input') then
+      InputFiles.Add(OptionArg(I))
+    else If Checkoption(I,'e','extension') then
+      UseExt:=OptionArg(I)
+    else if CheckOption(I,'f','fixheader') then
+      RunMode:=rmFixHeader
+    else if CheckOption(I,'6','64bit') then
+      Use64bit:=True
+    else if CheckOption(I,'h','help') then
+      Usage(0)
+    else if CheckOption(I,'v','verbose') then
+      BeVerbose:=True
+    else
+      begin
+      P:=ParamStr(I);
+      if (Length(P)>0) and (P[1]<>'-') then
+        begin
+        if (I=ParamCount) then
+          OutputFileName:=P
+        else
+          InputFiles.Add(P)
+        end
+      else
+        begin
+        DoError(SErrUnknownParam,[P]);
+        Usage(1);
+        end;
+      end;
+    end;
+  If (InputFiles.Count=0) then
+    DoError(SErrNoInputFile,[]);
+  If (InputFiles.Count>1) and (OutputFileName<>'') then
+    DoError(SErrNoOutputFile,[]);
+  If (RunMode=rmFixHeader) and (OutputFileName<>'') then
+    DoError(SErrOutputFileIllegal,[])
+end;
+
+Type
+  TLogger = Class(TObject)
+    Procedure Log(Const Msg : String);
+  end;
+
+Procedure TLogger.Log(Const Msg : string);
+
+begin
+  Writeln(Msg);
+end;
+
+Procedure FixHeader(AFileName : String);
+
+Var
+  F : TElfResourceFixer;
+  O : TLogger;
+  
+begin
+  if Use64bit then
+    F:=TElf64ResourceFixer.Create
+  else
+    F:=TElf32ResourceFixer.Create;
+  try
+    F.Verbose:=BeVerbose;
+    if BeVerbose then
+      begin
+      O:=TLogger.Create;
+      F.OnVerbose:={$ifdef fpc}@{$endif}O.Log;
+      end
+    else
+      O:=Nil;
+    Try
+      F.FixFile(AFileName);
+    Finally
+      O.Free;
+    end;
+  Finally
+    F.Free;
+  end;
+end;
+
+Procedure CreateRes(AFileName : String);
+
+Var
+  C : TElfResCreator;
+
+begin
+  If Use64Bit then
+    C:=TElf64ResCreator.Create
+  else
+    C:=TElf32ResCreator.Create;
+  With C do
+    Try
+      Verbose:=BeVerbose;
+      If (UseExt<>'') then
+        Extension:=UseExt;
+      Convert(AFileName,OutputFileName);
+    Finally
+      Free;
+    end;
+end;
+
+Procedure Run;
+
+Var
+  I : Integer;
+  
+begin
+  Try
+    Case RunMode of
+      rmFixHeader:
+        For I:=0 to InputFiles.Count-1 do
+          FixHeader(InputFiles[i]);
+      rmCreateElfRes:
+        For I:=0 to InputFiles.Count-1 do
+          CreateRes(InputFiles[i]);
+    end;
+  except
+    On E : Exception do
+      begin
+      Writeln(SError,' ',E.Message);
+      Halt(1);
+      end;
+  end;
+end;
+
+begin
+  InputFiles:=TStringList.Create;
+  Try
+    AnalyzeParams;
+    Run;
+  Finally
+    FreeAndNil(InputFiles);
+  end;
+end.
+