# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem          1.0

name                fpc
version             3.2.2
categories          lang pascal
platforms           macosx
license             {GPL-2 LGPL-2}
maintainers         {@kamischi web.de:karl-michael.schindler} \
                    {@barracuda156 gmail.com:vital.had} \
                    openmaintainer
description         Free Pascal, an open source Pascal and Object Pascal \
                    compiler.
long_description    Free Pascal is a 32, 64 and 16 bit professional Pascal \
                    compiler. It can target many processor architectures: \
                    Intel x86 (including 8086), AMD64/x86-64, PowerPC, \
                    PowerPC64, SPARC, ARM, AArch64, MIPS and the JVM. \
                    Supported operating systems include Linux, FreeBSD, \
                    Mac OS X/iOS/iPhoneSimulator/Darwin, Win32, Win64, WinCE \
                    and Android.
homepage            https://www.freepascal.org

# TODO: add support for i386
supported_archs     x86_64 arm64 ppc ppc64

# Bootstrap compiler version
set boot_v          3.0.4

master_sites        sourceforge:freepascal:main \
                    https://downloads.freepascal.org/fpc/dist/${boot_v}/bootstrap/:bootstrap \
                    https://downloads.freepascal.org/fpc/dist/${boot_v}/powerpc-macosx/:bootstrap \
                    https://downloads.freepascal.org/fpc/dist/${version}/i386-macosx/:bootstrap

set src             ${name}build-${version}.tar.gz
checksums           ${src} \
                    rmd160  3106b4aff1adc4cd08dfdd39cc3ef4e800888255 \
                    sha256  85ef993043bb83f999e2212f1bca766eb71f6f973d362e2290475dbaaf50161f \
                    size    84195619
# PowerPC compiler is only available as a dmg
if {${configure.build_arch} in [list ppc ppc64]} {
    set pp          fpc-${boot_v}.powerpc-macosx.dmg
    checksums-append \
                    ${pp} \
                    rmd160  c1dbe7fb71382a69146023b2cdac768e05fea8e3 \
                    sha256  587a6ae199d2fb992794c6b4ff9a7aa0c4646687ed5bbab5a6c96bdc322ba53c \
                    size    98748823
# MacOSX < 10.8 requires bootstrap compiler from dmg
} elseif {${os.platform} eq "darwin" && ${os.major} <= 12} { # 10.8, Mountain Lion
    set pp          fpc-${version}.intelarm64-macosx.dmg
    checksums-append \
                    ${pp} \
                    rmd160  600bc2e86e450bba748f3fa54939fb96db0eee41 \
                    sha256  05d4510c8c887e3c68de20272abf62171aa5b2ef1eba6bce25e4c0bc41ba8b7d \
                    size    274206896

} else {
    set pp          x86_64-macosx-10.9-ppcx64.tar.bz2
    checksums-append \
                    ${pp} \
                    rmd160  7c5327aa6f4fd8616d78bc4f708463b9fb3e8844 \
                    sha256  0515ad4251c51fa7e5c0ff9b1d90ea50f41530b56276cc72b73798fae437b3b4 \
                    size    1556308
}
distfiles           ${src}:main ${pp}:bootstrap

# doesn't install shared libraries
installs_libs       no

# parallel building is unreliable
use_parallel_build  no

extract.only        ${src}

use_configure       no
universal_variant   no

set fpcbasepath     ${prefix}/libexec/${name}

if {${os.platform} eq "darwin" && ${os.major} >= 22} { # macOS 13, Ventura
# fix obsolete linker options
    patchfiles-append   t_darwin.pas.patch
}

if {${os.platform} eq "darwin" && ${os.major} >= 24 && ${build_arch} eq "x86_64"} { # macOS 15, Sequoia
# this fix will be part of version 3.2.4
    patchfiles-append   rautils.patch
}

subport "chmcmd-${name}" {
    revision        0

    description     The FPC Pascal htmlhelp (CHM) compiler
    long_description \
                    chmcmd is a cross-platform utility to generate compressed \
                    HTML (.chm) documentation, written in Free Pascal.

    depends_build-append \
                    port:${name}
    extract.post_args-append \
                    ${name}build-${version}/fpcsrc/packages/chm \
                    ${name}build-${version}/fpcsrc/packages/fcl-xml \
                    ${name}build-${version}/fpcsrc/packages/fcl-base \
                    ${name}build-${version}/fpcsrc/packages/fcl-process \
                    ${name}build-${version}/fpcsrc/packages/fpmkunit \
                    ${name}build-${version}/fpcsrc/packages/hash \
                    ${name}build-${version}/fpcsrc/packages/iconvenc \
                    ${name}build-${version}/fpcsrc/packages/libtar \
                    ${name}build-${version}/fpcsrc/packages/paszlib \
                    ${name}build-${version}/fpcsrc/packages/univint \
                    ${name}build-${version}/fpcsrc/rtl
    worksrcdir      ${name}build-${version}/fpcsrc/packages/chm
    use_configure   yes
    configure.cmd   ${fpcbasepath}/bin/fpcmake
    configure.pre_args
    configure.args  -r -v Makefile.fpc.fpcmake
    configure.post_args

    patchfiles-delete   t_darwin.pas.patch

    build.env       PREFIX=${prefix}
    build.target
    build.post_args-append \
                    V=1 VERBOSE=1
    destroot {
        xinstall -m 0755 ${build.dir}/chmcmd ${destroot}${prefix}/bin
    }
}

subport "${name}-cross" {
    revision        0

    description     FreePascal common cross-compiler binaries
    long_description \
                    Crosscompilers serving as starting points \
                    for specific operating system targets.    \
                    OS runtime libraries are not yet ready.
    categories-append \
                    cross
    depends_build-append \
                    port:${name}

    worksrcdir      ${name}build-${version}/fpcsrc/compiler
    use_configure   no
    patch.pre_args-replace  -p0 -p1
    build.args      OPT="-ap -v0"
    build.target    aarch64 arm avr i386 i8086 jvm m68k mips mipsel \
                    powerpc powerpc64 sparc sparc64 x86_64
    switch ${build_arch} {
        ppc {
            build.target-delete powerpc i386 i8086
        }
        ppc64 {
            build.target-delete powerpc64 i386 i8086
        }
        i386 {
            build.target-delete i386
        }
        x86_64 {
            build.target-delete x86_64
        }
        arm64 {
            build.target-delete aarch64 i386 i8086
        }
    }
    destroot {
      # delete unwanted files
        file delete -force ${worksrcpath}/ppcgen
        file delete        {*}[glob ${worksrcpath}/ppc*.*]

      # create dirs
        xinstall -m 0755 -d ${destroot}${prefix}/bin
        xinstall -m 0755 -d ${destroot}${prefix}/lib/fpc/${version}

      # loop over installing all cross-compilers
        foreach PPCCROSS [glob -tails -directory ${worksrcpath} ppc*] {
            xinstall -m 0755 ${worksrcpath}/$PPCCROSS \
                    ${destroot}${prefix}/lib/fpc/${version}
            ln -sf ../lib/fpc/${version}/$PPCCROSS \
                    ${destroot}${prefix}/bin/$PPCCROSS
        }
    }
}

subport "${name}-cross-arm-wince" {
    revision                1
    categories-append       cross
    supported_archs         noarch
    worksrcdir              fpcbuild-${version}/fpcsrc
    use_parallel_build      no
    use_configure           no
    depends_build-append    port:${name} port:${name}-cross
    build.target            rtl packages
    destroot.target         rtl_install packages_install
    test.target

# target specifics
    description     FPC cross-compiler for arm-wince
    long_description \
        This Pascal crosscompiler produces arm executables, \
        which run natively on arm-wince systems. \n \
        Get help with: \n \
        fpc -h \n \
        Compile and link a Pascal file with: \n \
        \n \
        fpc -Parm -Twince FILENAME

    build.args      PP=ppcarm CPU_TARGET=arm OS_TARGET=wince OPT="-ap -v0"
    destroot.args   CPU_TARGET=arm OS_TARGET=wince CROSSINSTALL=1 \
                    INSTALL_PREFIX=${destroot}${prefix}/libexec/fpc

# remove duplicate doc and bin files
    post-destroot   {
        file delete -force ${destroot}${prefix}/libexec/fpc/share
        file delete -force ${destroot}${prefix}/libexec/fpc/bin
    }
}

foreach ostarget {nativent win32 wince} {
    subport "${name}-cross-i386-$ostarget" {
        revision                1
        categories-append       cross
        supported_archs         i386 x86_64 noarch
        worksrcdir              fpcbuild-${version}/fpcsrc
        use_parallel_build      no
        use_configure           no
        depends_build-append    port:${name} port:${name}-cross
        build.target            rtl packages
        destroot.target         rtl_install packages_install
        test.target

# target specifics
        description     FPC cross-compiler for i386-$ostarget
        long_description \
            This Pascal crosscompiler produces i386 executables, \
            which run natively on i386-$ostarget systems. \n \
            Get help with: \n \
            fpc -h \n \
            Compile and link a Pascal file with: \n \
            \n \
            fpc -Pi386 -T$ostarget FILENAME

        build.args      PP=ppc386 CPU_TARGET=i386 OS_TARGET=$ostarget \
                        OPT="-ap -v0"
        destroot.args   CPU_TARGET=i386 OS_TARGET=$ostarget CROSSINSTALL=1 \
                        INSTALL_PREFIX=${destroot}${prefix}/libexec/fpc

# remove duplicate doc and bin files
        post-destroot   {
            file delete -force ${destroot}${prefix}/libexec/fpc/share
            file delete -force ${destroot}${prefix}/libexec/fpc/bin
        }
    }
}

subport "${name}-cross-x86-64-win64" {
    PortGroup   obsolete 1.0

    replaced_by ${name}-cross-x86_64-win64
    revision    1
}

subport "${name}-cross-x86_64-win64" {
    revision                1
    categories-append       cross
    supported_archs         noarch
    worksrcdir              fpcbuild-${version}/fpcsrc
    use_parallel_build      no
    use_configure           no
    depends_build-append    port:${name} port:${name}-cross
    build.target            rtl packages
    destroot.target         rtl_install packages_install
    test.target

# target specifics
    description     FPC cross-compiler for x86_64-win64
    long_description \
        This Pascal crosscompiler produces x86_64 executables, \
        which run natively on x86_64-win64 systems. \n \
        Get help with: \n \
        fpc -h \n \
        Compile and link a Pascal file with: \n \
        \n \
        fpc -Px86_64 -Twin64 FILENAME

    build.args      PP=ppcx64 CPU_TARGET=x86_64 OS_TARGET=win64 OPT="-ap -v0"
    destroot.args   CPU_TARGET=x86_64 OS_TARGET=win64 CROSSINSTALL=1 \
                    INSTALL_PREFIX=${destroot}${prefix}/libexec/fpc

# remove duplicate doc and bin files
    post-destroot   {
        file delete -force ${destroot}${prefix}/libexec/fpc/share
        file delete -force ${destroot}${prefix}/libexec/fpc/bin
    }
}

# may also support: Linux6432 embedded solaris AROS Android Haiku
foreach ostarget {linux dragonfly freebsd netbsd openbsd} {
    subport "${name}-cross-x86_64-$ostarget" {
        revision                1
        categories-append       cross
        supported_archs         i386 x86_64 noarch
        worksrcdir              fpcbuild-${version}/fpcsrc
        use_parallel_build      no
        use_configure           no
        depends_build-append    port:${name} port:${name}-cross port:x86_64-${ostarget}-binutils
        build.target            rtl packages
        destroot.target         rtl_install packages_install
        test.target

# target specifics
        description     FPC cross-compiler for x86_64-$ostarget
        long_description \
            This Pascal crosscompiler produces x86_64 executables, \
            which run natively on x86_64-$ostarget systems. \n \
            Get help with: \n \
            fpc -h \n \
            Compile and link a Pascal file with: \n \
            \n \
            fpc -Px86_64 -T$ostarget FILENAME

        build.args      PP=ppcx64 CPU_TARGET=x86_64 OS_TARGET=$ostarget \
                        OPT="-ap -v0"
        destroot.args   CPU_TARGET=x86_64 OS_TARGET=$ostarget CROSSINSTALL=1 \
                        INSTALL_PREFIX=${destroot}${prefix}/libexec/fpc/

# remove duplicate doc and bin files
        post-destroot   {
            file delete -force ${destroot}${prefix}/libexec/fpc/share
            file delete -force ${destroot}${prefix}/libexec/fpc/bin
        }
    }
}

# may also support: amiga macosclassic darwin morphos embedded wii aix
foreach ostarget {linux netbsd} {
    subport "${name}-cross-powerpc-$ostarget" {
        revision                1
        categories-append       cross
        supported_archs         noarch
        worksrcdir              fpcbuild-${version}/fpcsrc
        use_parallel_build      no
        use_configure           no
        depends_build-append    port:${name} port:${name}-cross port:powerpc-${ostarget}-binutils
        build.target            rtl packages
        destroot.target         rtl_install packages_install
        test.target

# target specifics
        description     FPC cross-compiler for powerpc-$ostarget
        long_description \
            This Pascal crosscompiler produces powerpc executables, \
            which run natively on powerpc-$ostarget systems. \n \
            Get help with: \n \
            fpc -h \n \
            Compile and link a Pascal file with: \n \
            \n \
            fpc -Ppowerpc -T$ostarget FILENAME

        build.args      PP=ppcppc CPU_TARGET=powerpc OS_TARGET=$ostarget \
                        OPT="-ap -v0"
        destroot.args   CPU_TARGET=powerpc OS_TARGET=$ostarget CROSSINSTALL=1 \
                        INSTALL_PREFIX=${destroot}${prefix}/libexec/fpc/

# remove duplicate doc and bin files
        post-destroot   {
            file delete -force ${destroot}${prefix}/libexec/fpc/share
            file delete -force ${destroot}${prefix}/libexec/fpc/bin
        }
    }
}

if {${subport} eq "${name}"} {
    revision            1

    installs_libs       yes

    if {${os.platform} eq "darwin" \
        && ${configure.build_arch} in [list ppc ppc64]} {
        post-extract {
            xinstall -d ${workpath}/tmp/boot
            system "hdiutil attach ${distpath}/${pp} -private -nobrowse \
                    -mountpoint ${workpath}/tmp/boot"
            copy ${workpath}/tmp/boot/${name}-${boot_v}.powerpc-macosx.pkg \
                    ${workpath}/pkg
            system "hdiutil detach ${workpath}/tmp/boot -force"
            delete -force ${workpath}/tmp/boot
            system -W ${workpath} "gunzip -d pkg/Contents/Archive.pax.gz"
            system -W ${workpath}/pkg "pax -r < Contents/Archive.pax"
            copy ${workpath}/pkg/usr/local/lib/${name}/${boot_v}/${bootstrapCompiler} \
                    ${workpath}
        }
    } elseif {${os.platform} eq "darwin" \
              && ${os.major} <= 12} { # 10.8, Mountain Lion
        post-extract {
            xinstall -d ${workpath}/tmp/boot
            system "hdiutil attach ${distpath}/${pp} -private -nobrowse \
                    -mountpoint ${workpath}/tmp/boot"
            copy ${workpath}/tmp/boot/${name}-${version}-intelarm64-macosx.mpkg \
                    ${workpath}/pkg
            system "hdiutil detach ${workpath}/tmp/boot -force"
            delete -force ${workpath}/tmp
            system -W ${workpath} "pkgutil --expand \
                    pkg/Contents/Packages/${name}-${version}-intelarm64-macosx.pkg \
                    content"
            system -W ${workpath}/content "gzip -dc Payload | cpio -id"
            copy ${workpath}/content/usr/local/lib/${name}/${version}/${bootstrapCompiler} \
                    ${workpath}
        }
    } else {
        extract.only-append ${pp}
    }

    post-patch {
        # adjust the path "codfilepath" for plex
        # from /usr/local to MacPort's prefix.
        reinplace "s|/usr/local|${prefix}|g" \
            ${worksrcpath}/utils/tply/pyacc.y \
            ${worksrcpath}/utils/tply/pyacc.pas \
            ${worksrcpath}/utils/tply/plex.pas
    }

    switch ${build_arch} {
        x86_64 {
            set bootstrapCompiler ppcx64
            set cpuTarget x86_64
            set compiler ppcx64
        }
        arm64 {
            set bootstrapCompiler ppcx64
            set cpuTarget aarch64
            set compiler ppca64
        }
        ppc {
            set bootstrapCompiler ppcppc
            set cpuTarget powerpc
            set compiler ppcppc
        }
        ppc64 {
            set bootstrapCompiler ppcppc64
            set cpuTarget powerpc64
            set compiler ppcppc64
        }
        default {
            set bootstrapCompiler unsupported
            set cpuTarget unsupported
            set compiler unsupported
        }
    }

    if {${os.platform} eq "darwin"} {
        if       {${os.major} >= 20} { # 11, Big Sur
            set otherOptions "-WM11.0 -XR${configure.sdkroot}"
        } elseif {${os.major} >= 13} { # 10.9, Mavericks
            set otherOptions "-WM10.9"
        } elseif {${configure.build_arch} in [list ppc ppc64]} {
            # Relevant only for macOS PowerPC
            patchfiles-append patch-powerpc.diff
            # On Tiger building is trivial
            if {${os.major} == 8} {
                set otherOptions "-WM10.4"
            } else {
                # At the moment linking fails for pas2js on 10.5 and 10.6
                # with the system or cctools ld. ld_classic works,
                # but it does not link against 10.5+ SDK. Therefore,
                # use 10.4 SDK for all PowerPC. See:
                # https://gitlab.com/freepascal.org/fpc/source/-/issues/40625
                macosx_deployment_target 10.4
                set tiger_sdkpath ${developer_dir}/SDKs/MacOSX10.4u.sdk
                if {![file exists $tiger_sdkpath]} {
                    pre-fetch {ui_error "Building ${name} requires 10.4 SDK"}
                }
                # We use symlinks to needed tools, but make sure those
                # have not been created already:
                set binutils_path ${workpath}/bin
                pre-build {
                    if {![file exists $binutils_path]} {
                        xinstall -m 0755 -d ${workpath}/bin
                        ln -s /usr/bin/as ${workpath}/bin/as
                        ln -s /usr/bin/ld_classic ${workpath}/bin/ld
                    }
                }
                set otherOptions "-WM${macosx_deployment_target} \
                        -XR${tiger_sdkpath} -Fl=/usr/lib -FD${binutils_path}"
            }
        } else   {
            set otherOptions ""
        }
    }

    worksrcdir          ${name}build-${version}/fpcsrc
    build.env           PP=${workpath}/${bootstrapCompiler} \
                        PREFIX=${destroot}${fpcbasepath}
    build.args          OPT="-v0 -ap ${otherOptions}" CPU_TARGET=${cpuTarget} \
                        UTILS=1

    destroot.args       {*}${build.args}
    destroot.env        {*}${build.env}

    # codesign for older systems does not have a --remove-signature option
    # work around: replace codesign by a dummy.
    if {${os.platform} eq "darwin" && ${os.major} <= 15} { # 10.11, El Capitan
        build.args-append   CODESIGN=/usr/bin/true
    }

    # build the compiler utilities msgdif and msg2inc
    post-build {
        system -W ${worksrcpath}/compiler/utils \
               "../${compiler} -ap -v0 -Fu../../rtl/units/${cpuTarget}-darwin \
                  ${otherOptions} msgdif.pp && \
                ../${compiler} -ap -v0 -Fu../../rtl/units/${cpuTarget}-darwin \
                  ${otherOptions} msg2inc.pp"
    }

    post-destroot {
        # create a symlink to the architecture dependent executable
        ln -s ${fpcbasepath}/lib/${name}/${version}/${compiler} \
                ${destroot}${fpcbasepath}/bin
        # target arm64 needs make utils_install explicitly
        if {${build_arch} == "arm64"} {
            system -W ${worksrcpath} \
                "make utils_install FPC=${worksrcpath}/compiler/${compiler} \
                    PREFIX=${destroot}${fpcbasepath} \
                    OPT=\"-Furtl/units/${cpuTarget}-darwin -ap -v0 \
                    ${otherOptions}\""
        }
        # generate a configuration file
        xinstall -d ${destroot}${fpcbasepath}/etc
        system -W ${destroot}${fpcbasepath} \
            "bin/fpcmkcfg -d basepath=${fpcbasepath}/lib/${name}/${version} \
                    -o etc/fpc.cfg"
        ln -s ${fpcbasepath}/etc/fpc.cfg ${destroot}${prefix}/etc
        system "patch ${destroot}${fpcbasepath}/etc/fpc.cfg \
                    ${filespath}/fpc.cfg.patch"

        # remove the -WM option for older systems or update it as needed
        if {${os.platform} eq "darwin"} {
            if {${configure.build_arch} in [list ppc ppc64]} { # macOS PowerPC
                reinplace "s|-WM10.9|-WM10.4|g" \
                    ${destroot}${fpcbasepath}/etc/fpc.cfg
            } elseif {${os.major} < 11}   { # 10.7, Lion
                reinplace "s|-WM10.9||g" ${destroot}${fpcbasepath}/etc/fpc.cfg
            } elseif {${os.major} >=  20} { # 11, Big Sur
                reinplace "s|-WM10.9|-WM11.0|g" \
                    ${destroot}${fpcbasepath}/etc/fpc.cfg
            }
            if {${os.major} < 13} {
                reinplace "s|/Applications/Xcode.app/Contents/Developer||g" \
                        ${destroot}${fpcbasepath}/etc/fpc.cfg
            }
        }

        # set prefix of search path for qt4pas
        reinplace "s|PREFIX|${prefix}|g" ${destroot}${fpcbasepath}/etc/fpc.cfg

        # install man
        xinstall -d ${destroot}${fpcbasepath}/man
        foreach d {1 5} {
            file copy ${workpath}/${name}build-${version}/install/man/man${d} \
                ${destroot}${fpcbasepath}/man
            foreach f [glob ${destroot}${fpcbasepath}/man/man${d}/*.${d}] {
                system "/usr/bin/gzip ${f}"
            }
        }
        ln -s ${fpcbasepath}/man/man1/fpc.1.gz \
            ${destroot}${prefix}/share/man/man1
        ln -s ${fpcbasepath}/man/man5/fpc.cfg.5.gz \
            ${destroot}${prefix}/share/man/man5

        # chmcmd will be installed by the chmcmd-fpc subport
        file delete -force ${destroot}${fpcbasepath}/bin/chmcmd
        foreach b [glob -nocomplain ${destroot}${fpcbasepath}/bin/*] {
            set n [file tail ${b}]
            ln -s ${fpcbasepath}/bin/${n} ${destroot}${prefix}/bin
        }

        # install the compiler utilities msgdif and msg2inc
        xinstall -m 0755 -W ${worksrcpath}/compiler/utils msgdif msg2inc \
                ${destroot}${prefix}/bin
    }

    notes "
        The compiler fpc looks for the fpc.cfg file in the following places:
        - The current directory.
        - Home directory, looks for .fpc.cfg
        - The directory specified in the environment variable PPC_CONFIG_PATH,\
          and if it's not set under compilerdir/../etc.
        - If it is not yet found: in /etc.

        All the files of fpc are installed in ${fpcbasepath} and\
        the executables are installed in ${fpcbasepath}/bin. The fpc.cfg\
        is installed in ${fpcbasepath}/etc to make fpc find fpc.cfg.\
        To customize, use ~/.fpc.cfg or /etc/fpc.cfg and call\
        ${fpcbasepath}/bin/fpc directly.
    "

    livecheck.distname  ${name}
} else {
    livecheck.type      none
}
