#
#   Makefile.fpc for Free Pascal Source Tree
#

[package]
name=fpc
version=3.3.1

[target]
dirs=compiler rtl utils packages installer

[require]
nortl=y

[install]
fpcpackage=y

[default]
fpcdir=.
rule=help

[prerules]
REQUIREDVERSION=3.2.2
REQUIREDVERSION2=3.2.0


# make versions < 3.77 (OS2 version) are buggy
ifndef inOS2
override FPCDIR:=$(BASEDIR)
export FPCDIR
endif

# Build dir
ifndef BUILDDIR
BUILDDIR=$(BASEDIR)/build
endif

# New ppc386 (or ppc68k if on m68k machine !)
ifndef PPNEW
ifeq ($(CPU_TARGET),m68k)
PPSUF=68k
endif
ifeq ($(CPU_TARGET),i386)
PPSUF=386
endif
ifeq ($(CPU_TARGET),x86_64)
PPSUF=x64
endif
ifeq ($(CPU_TARGET),sparc)
PPSUF=sparc
endif
ifeq ($(CPU_TARGET),sparc64)
PPSUF=sparc64
endif
ifeq ($(CPU_TARGET),powerpc)
PPSUF=ppc
endif
ifeq ($(CPU_TARGET),powerpc64)
PPSUF=ppc64
endif
ifeq ($(CPU_TARGET),alpha)
PPSUF=axp
endif
ifeq ($(CPU_TARGET),arm)
PPSUF=arm
endif
ifeq ($(CPU_TARGET),armeb)
PPSUF=arm
endif
ifeq ($(CPU_TARGET),jvm)
PPSUF=jvm
endif
ifeq ($(CPU_TARGET),mips)
PPSUF=mips
endif
ifeq ($(CPU_TARGET),mipsel)
PPSUF=mipsel
endif
ifeq ($(CPU_TARGET),i8086)
PPSUF=8086
endif
ifeq ($(CPU_TARGET),avr)
PPSUF=avr
endif
ifeq ($(CPU_TARGET),aarch64)
PPSUF=a64
endif
ifeq ($(CPU_TARGET),riscv32)
PPSUF=rv32
endif
ifeq ($(CPU_TARGET),riscv64)
PPSUF=rv64
endif
ifeq ($(CPU_TARGET),xtensa)
PPSUF=xtensa
endif
ifeq ($(CPU_TARGET),z80)
PPSUF=z80
endif
ifeq ($(CPU_TARGET),wasm32)
PPSUF=wasm32
endif
ifeq ($(CPU_TARGET),loongarch64)
PPSUF=loongarch64
endif

# cross compilers uses full cpu_target, not just ppc-suffix
# (except if the target cannot run a native compiler)
ifdef CROSSCOMPILE
ifneq ($(CPU_TARGET),jvm)
PPPRE=ppcross
else
PPPRE=ppc
endif
else
PPPRE=ppc
endif

PPNEW=$(BASEDIR)/compiler/$(PPPRE)$(PPSUF)$(SRCEXEEXT)
endif

# Use FPCFPMAKENEW to explicitly specify FPCFPMAKE.
# Otherwise fpmkunit build will use wrong (starting) compiler
# if there has been no compiler binary available in the compiler
# dir before running make.
ifndef FPCFPMAKENEW
ifdef CROSSCOMPILE
FPCFPMAKENEW=$(BASEDIR)/compiler/ppc$(SRCEXEEXT)
else
FPCFPMAKENEW=$(PPNEW)
endif
endif

# Check if install/ subdir is available
ifneq ($(wildcard install),)
CVSINSTALL=install
else
CVSINSTALL=.
endif

# Install target, for snapshots we don't install examples.
# Cross installation only needs the .ppu files
ifdef SNAPSHOT
INSTALLTARGET=install
else
ifdef CROSSINSTALL
INSTALLTARGET=install
else
INSTALLTARGET=distinstall
endif
endif

# All target
ifdef SNAPSHOT
ALLTARGET=all
else
ifndef ALLTARGET
SHAREDTARGETS=
SMARTTARGETS=win32 go32v2 linux freebsd netbsd openbsd netware netwlibc darwin
ifneq ($(findstring $(OS_TARGET),$(SHAREDTARGETS)),)
ALLTARGET=shared
else
ifneq ($(findstring $(OS_TARGET),$(SMARTTARGETS)),)
ALLTARGET=smart
else
ALLTARGET=all
endif
endif
endif
endif
# Prefix for units
ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
PKGUNITSPRE=u
else
PKGUNITSPRE=units-
endif

# Cross compile needs a prefix to not conflict with original packages
ifdef CROSSINSTALL
PKGPRE=$(FULL_TARGET)-
else
PKGPRE=
endif

# Always compile for release
override RELEASE=1
export RELEASE

# We want to have the resulting .zips in the current dir
ifndef DIST_DESTDIR
export DIST_DESTDIR:=$(BASEDIR)
endif

# Temporary path to pack a file
BASEPACKDIR=$(BASEDIR)/basepack

# Always use newly created fpcmake
ifndef FPCMAKENEW
ifdef CROSSCOMPILE
# Use bootstrapped fpcmake when cross-compiling
FPCMAKENEW=$(BASEDIR)/utils/fpcm/fpcmake$(SRCEXEEXT)
else
# Use normal fpcmake
FPCMAKENEW=$(BASEDIR)/utils/fpcm/bin/$(SOURCESUFFIX)/fpcmake$(SRCEXEEXT)
endif
endif

# Build/install options
ifneq ($(OPT),)
OPTNEW+=$(OPT)
endif

# some targets do not generate PIC by default so we have select explicitly
# the general threading model when compiling the final versions of rtl and packages
ifneq ($(findstring $(OS_TARGET),linux),)
ifneq ($(findstring $(CPU_TARGET),i386 arm),)
override OPTNEW+=-CVglobal-dynamic
endif
endif

CLEANOPTS=FPC=$(PPNEW)
BUILDOPTS=FPC=$(PPNEW) FPCFPMAKE=$(FPCFPMAKENEW) RELEASE=1 'OPT=$(OPTNEW)' 'FPCMAKEOPT=$(OPT)'
ifdef CROSSCOMPILE
ifneq ($(CROSSASPROG),)
BUILDOPTS+=ASPROG=$(CROSSASPROG)
endif
ifneq ($(CROSSASTARGET),)
BUILDOPTS+=ASTARGET=$(CROSSASTARGET)
endif
endif
INSTALLOPTS=FPC=$(PPNEW) ZIPDESTDIR=$(BASEDIR) FPCMAKE=$(FPCMAKENEW)

# CPU targets for which we only build the compiler/rtl
BuildOnlyBaseCPUs=jvm

ifneq ($(wildcard utils),)
NOUTILSTARGETS=embedded gba nds msdos win16 macosclassic $(BuildOnlyBaseCPUs) freertos
ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
ifdef BUILDFULLNATIVE
UTILS=1
endif
endif
endif

INSTALLERTARGETS=emx go32v2 msdos os2
ifneq ($(findstring $(OS_TARGET),$(INSTALLERTARGETS)),)
INSTALLER=1
endif

[rules]
# These values can change
unexport FPC_VERSION FPC_COMPILERINFO OS_SOURCE

# Only process directories that really exists
override TARGET_DIRS:=$(wildcard $(TARGET_DIRS))

#####################################################################
# Main targets
#####################################################################

.PHONY: help

help:
        @$(ECHO)
        @$(ECHO) Targets
        @$(ECHO)    all         Build a new compiler and all packages
        @$(ECHO)    install     Install newly build files
        @$(ECHO)    zipinstall  Create zip/tar of installed files
        @$(ECHO)    singlezipinstall  Alias for zipinstall
        @$(ECHO)
        @exit


#####################################################################
# Dependencies
#####################################################################

#######################################
# Compiler
#######################################

.PHONY: compiler_cycle

compiler_cycle:
        $(MAKE) -C compiler cycle


##########################################################################
# Packaging
##########################################################################

BUILDSTAMP=build-stamp.$(FULL_TARGET)

.PHONY: all clean distclean build buildbase install installbase
.PHONY: installother zipinstallbase zipinstallotherzipinstall
.PHONY: singlezipinstall versioncheckstartingcompiler

versioncheckstartingcompiler:
ifndef CROSSCOMPILE
ifneq ($(FPC_VERSION),$(REQUIREDVERSION))
ifneq ($(FPC_VERSION),$(REQUIREDVERSION2))
ifndef OVERRIDEVERSIONCHECK
	$(error The only supported starting compiler version is $(REQUIREDVERSION). You are trying to build with $(FPC_VERSION).)
else
	@$(ECHO) You have overriden the starting compiler versioncheck while using starting compiler version $(FPC_VERSION). This situation is not supported and strange things and errors may happen. Remove OVERRIDEVERSIONCHECK=1 to fix this.
endif
endif
endif
endif

ifeq ($(findstring $(CPU_TARGET),$(BuildOnlyBaseCPUs)),)
all: versioncheckstartingcompiler build
install: installall
zipinstall: zipinstallall
else
all: versioncheckstartingcompiler buildbase
install: installbase
zipinstall: zipinstallbase
endif

clean: $(addsuffix _distclean,$(TARGET_DIRS))
        -$(DEL) build-stamp.*
        -$(DEL) base.build-stamp.*

distclean: clean

build: $(BUILDSTAMP)
$(BUILDSTAMP):
# create new compiler
        $(MAKE) compiler_cycle RELEASE=1
ifdef CROSSCOMPILE
# Buld a new native fpcmake when cross-compiling.
# Fresh native compiler and RTL are ready at this stage.
        $(MAKE) -C utils/fpcm bootstrap $(BUILDOPTS)
endif
# clean
        $(MAKE) rtl_clean $(CLEANOPTS)
        $(MAKE) packages_clean $(CLEANOPTS)
ifdef UTILS
        $(MAKE) utils_clean $(CLEANOPTS)
endif
ifdef INSTALLER
        $(MAKE) installer_clean $(CLEANOPTS)
endif
# build everything
        $(MAKE) rtl_$(ALLTARGET) $(BUILDOPTS)
        $(MAKE) packages_$(ALLTARGET) $(BUILDOPTS)
ifdef UTILS
        $(MAKE) utils_all $(BUILDOPTS)
endif
ifdef INSTALLER
        $(MAKE) installer_all $(BUILDOPTS)
endif
        $(ECHOREDIR) Build > $(BUILDSTAMP)
        $(ECHOREDIR) Build > base.$(BUILDSTAMP)

buildbase: base.$(BUILDSTAMP)
base.$(BUILDSTAMP):
# create new compiler
        $(MAKE) compiler_cycle RELEASE=1
ifdef CROSSCOMPILE
# Buld a new native fpcmake when cross-compiling.
# Fresh native compiler and RTL are ready at this stage.
        $(MAKE) -C utils/fpcm bootstrap $(BUILDOPTS)
endif
# clean
        $(MAKE) rtl_clean $(CLEANOPTS)
# build everything
        $(MAKE) rtl_$(ALLTARGET) $(BUILDOPTS)
        $(ECHOREDIR) Build > base.$(BUILDSTAMP)

installbase: base.$(BUILDSTAMP)
# create dirs
        $(MKDIR) $(INSTALL_BASEDIR)
        $(MKDIR) $(INSTALL_BINDIR)
# install compiler+rtl
        $(MAKE) compiler_$(INSTALLTARGET) $(INSTALLOPTS)
        $(MAKE) rtl_$(INSTALLTARGET) $(INSTALLOPTS)

installother:
        $(MAKE) packages_$(INSTALLTARGET) $(INSTALLOPTS)
ifdef UTILS
        $(MAKE) utils_$(INSTALLTARGET) $(INSTALLOPTS)
endif

zipinstallbase:
        $(MAKE) fpc_zipinstall ZIPTARGET=installbase ZIPNAME=base $(INSTALLOPTS)

zipinstallother:
        $(MAKE) packages_zip$(INSTALLTARGET) $(INSTALLOPTS) ZIPPREFIX=$(PKGUNITSPRE)
ifdef UTILS
        $(MAKE) utils_zip$(INSTALLTARGET) $(INSTALLOPTS)
endif


installall: $(BUILDSTAMP)
        $(MAKE) installbase $(INSTALLOPTS)
ifeq ($(findstring $(CPU_TARGET), $(BuildOnlyBaseCPUs)),)
        $(MAKE) installother $(INSTALLOPTS)
endif

singlezipinstall: zipinstallall
zipinstallall: $(BUILDSTAMP)
ifeq ($(FULL_SOURCE),$(FULL_TARGET))
	$(MAKE) fpc_zipinstall ZIPTARGET=install FULLZIPNAME=fpc-$(PACKAGE_VERSION).$(TARGETSUFFIX) $(INSTALLOPTS)
else
	$(MAKE) fpc_zipinstall ZIPTARGET=install FULLZIPNAME=fpc-$(PACKAGE_VERSION).$(TARGETSUFFIX).built.on.$(SOURCESUFFIX) $(INSTALLOPTS)
endif


##########################################################################
# Cross installation (installation of cross compiler and units)
##########################################################################

.PHONY: crossall crossinstall crosszipinstall crosssinglezipinstall

crossall:
        $(MAKE) all CROSSINSTALL=1

crossinstall:
        $(MAKE) install CROSSINSTALL=1

crosszipinstall:
        $(MAKE) zipinstall CROSSINSTALL=1

crosssinglezipinstall:
	$(MAKE) fpc_zipinstall ZIPTARGET=crossinstall FULLZIPNAME=fpc-$(PACKAGE_VERSION).$(SOURCESUFFIX).cross.$(TARGETSUFFIX) $(INSTALLOPTS)