From d570eabe538a7f7382be9374fb2a9f84d847689e Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 28 Aug 2005 09:31:26 +0000 Subject: [PATCH] + Added fpcres git-svn-id: trunk@954 - --- .gitattributes | 7 + utils/Makefile | 153 ++-- utils/Makefile.fpc | 1 + utils/fpcres/Makefile | 1519 ++++++++++++++++++++++++++++++++++++ utils/fpcres/Makefile.fpc | 22 + utils/fpcres/elfbfd.pas | 150 ++++ utils/fpcres/elfres.pas | 692 ++++++++++++++++ utils/fpcres/elfresfix.pas | 260 ++++++ utils/fpcres/fpcres.lpi | 171 ++++ utils/fpcres/fpcres.pas | 277 +++++++ 10 files changed, 3159 insertions(+), 93 deletions(-) create mode 100644 utils/fpcres/Makefile create mode 100644 utils/fpcres/Makefile.fpc create mode 100644 utils/fpcres/elfbfd.pas create mode 100644 utils/fpcres/elfres.pas create mode 100644 utils/fpcres/elfresfix.pas create mode 100644 utils/fpcres/fpcres.lpi create mode 100644 utils/fpcres/fpcres.pas diff --git a/.gitattributes b/.gitattributes index 3be0d39082..499d321df6 100644 --- a/.gitattributes +++ b/.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 diff --git a/utils/Makefile b/utils/Makefile index 1f35ca9d30..b57e7b3584 100644 --- a/utils/Makefile +++ b/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 diff --git a/utils/Makefile.fpc b/utils/Makefile.fpc index 25fcdc97c6..fb063a25fb 100644 --- a/utils/Makefile.fpc +++ b/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] diff --git a/utils/fpcres/Makefile b/utils/fpcres/Makefile new file mode 100644 index 0000000000..76fe4840b1 --- /dev/null +++ b/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 diff --git a/utils/fpcres/Makefile.fpc b/utils/fpcres/Makefile.fpc new file mode 100644 index 0000000000..59e793f782 --- /dev/null +++ b/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 diff --git a/utils/fpcres/elfbfd.pas b/utils/fpcres/elfbfd.pas new file mode 100644 index 0000000000..77ae5afd48 --- /dev/null +++ b/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. + diff --git a/utils/fpcres/elfres.pas b/utils/fpcres/elfres.pas new file mode 100644 index 0000000000..81f70470c7 --- /dev/null +++ b/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=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. diff --git a/utils/fpcres/elfresfix.pas b/utils/fpcres/elfresfix.pas new file mode 100644 index 0000000000..9692ee0395 --- /dev/null +++ b/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. diff --git a/utils/fpcres/fpcres.lpi b/utils/fpcres/fpcres.lpi new file mode 100644 index 0000000000..1957c03fea --- /dev/null +++ b/utils/fpcres/fpcres.lpi @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/utils/fpcres/fpcres.pas b/utils/fpcres/fpcres.pas new file mode 100644 index 0000000000..78ead0c43c --- /dev/null +++ b/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 Index2 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 (I0) 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. +