# -*- 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:tcls=4:sts=4

PortSystem          1.0
PortGroup           clang_dependency 1.0
PortGroup           gcc_dependency 1.0
PortGroup           perl5 1.0

name                perl5
version             5.34.3
categories          lang
platforms           darwin freebsd linux
license             {Artistic-1 GPL}
maintainers         nomaintainer

homepage            https://www.perl.org
master_sites        https://www.cpan.org/src/5.0/

# current Perl versions
#
# meaning of the fields:
# - version
# - subversion
# - revision
# - rmd160
# - sha256
# - size
set perl5.versions_info {
    5.16 3 12 f25fdd72449156a7cbe989e8bd339fdba1afabc0  bb7bc735e6813b177dcfccd480defcde7eddefa173b5967eac11babd1bfa98e8  13724906
    5.18 4 11 d97181a98f7acc80125b0d2a182a6a2cd7542ceb  1fb4d27b75cd244e849f253320260efe1750641aaff4a18ce0d67556ff1b96a5  14059430
    5.20 3 10 499846a1c92e00dd357cb782bc14787b8cd47051  1b40068166c242e34a536836286e70b78410602a80615143301e52aa2901493b  13743405
    5.22 4  8 54fdbcbf249134dc7d82b693417900286201b5e7  8b3122046d1186598082d0e6da53193b045e85e3505e7d37ee0bdd0bdb539b71  13745983
    5.24 4  7 8d6b67fc6d58334b2fdbfa9d6d7456265dca1f4e  e34ff38c54857f431f37403b757267c9998152bf46b5c750b462f62461279b10  14125130
    5.26 3  7 84ed404407c198ca2b8194c374c7914d941b6f49  9ff35a613213f29ab53975141af6825ae7d4408895538cac0922e47ab92a1477  14539342
    5.28 3  5 d2ae86e19666b689cad4c866e7d95c6491fd50c1  77dc1ddf541643af14d585867d3d0741cce45d0dbe8f1467024e63165d9e2fc5  12382032
    5.30 3  4 7aaec213f6537a53abd8fd97bb96d91b681cdf1e  6967595f2e3f3a94544c35152f9a25e0cb8ea24ae45f4bf1882f2e33f4a400f4  12375128
    5.32 1  3 ad9013fa389e3e73940c90b7d4ffd542a0cafc70  57cc47c735c8300a8ce2fa0643507b44c4ae59012bfdad0121313db639e02309  12610988
    5.34 3  1 092d75196ffa236528075c73bac365e1df9edb41  0b15c830a9a295c9f9439b6cda389300f0b18092686eaef47fbc9c92f5930ee1  12866356
    5.36 3  1 96c867d175fb54b631dbe9237e3d7df2c96ec8cb  45a228daef66d02fdccc820e71f87e40d8e3df1fc4431f8d4580ec08033866bd  13141248
    5.38 4  0 a065b3ec7a1b64886a1b98fe11171b03b5c97825  f6777e856b22460e8091f9524593e93299f421cc23dbd408d3f5ed3328d357a7  13716272
    5.40 2  0 93fd3e552473159524ee3d844ade4f1cfe5ff882  0551c717458e703ef7972307ab19385edfa231198d88998df74e12226abf563b  13923524
}

foreach {perl5.v perl5.subversion perl5.revision perl5.rmd160 perl5.sha256 perl5.size} ${perl5.versions_info} {
    subport perl${perl5.v} {
        set perl5.major     ${perl5.v}
        version             ${perl5.major}.[string range ${perl5.subversion} 0 0]
        set minor           [lrange [split ${version} .] 1 1]
        revision            ${perl5.revision}
        checksums           rmd160 ${perl5.rmd160} sha256 ${perl5.sha256} size ${perl5.size}

        description         Perl ${version} - Practical Extraction and Report Language
        long_description    Perl is a general-purpose programming language \
                            originally developed for text manipulation and now \
                            used for a wide range of tasks including system \
                            administration, web development, network \
                            programming, GUI development, and more.

        depends_lib-append  port:db48 \
                            port:gdbm

        if {${perl5.major} >= 5.24} {
            # Use a new enough compiler that perl_tsa_mutex_lock gets compiled in,
            # since perl modules may try to use it if they get compiled with a
            # newer compiler. See https://github.com/Perl/perl5/issues/18991
            compiler.blacklist-append \
                            {clang < 602} macports-clang-3.3 macports-clang-3.4
        }

        # https://trac.macports.org/ticket/59207
        platform darwin {
            if {${os.major} >= 19} {
                use_parallel_build  no
            }
        }

        distname            perl-${perl5.major}.${perl5.subversion}
        dist_subdir         perl${perl5.major}
        if {${perl5.major} >= 5.28} {
           use_xz           yes
        } else {
           use_bzip2        yes
        }

        # TODO: revise patch naming scheme
        patchfiles          ${perl5.major}/clean-up-paths.patch \
                            ${perl5.major}/avoid-no-cpp-precomp-PR38913.patch

        # Use correct location of db48 (Berkeley Data Base library)
        # https://trac.macports.org/ticket/55207
        patchfiles-append   ${perl5.major}/fix-db_file-paths.patch


        # - Prevent build from picking up the bind9 port's static libbind, which
        #   duplicates symbols from /usr/lib/libdl (r10638).
        # - Don't link against cryptlib
        #   https://trac.macports.org/ticket/53446
        patchfiles-append   ${perl5.major}/patch-Configure-remove-libs.diff

        # Prevent miniperl linking from accidentally finding our libstdc++
        # https://trac.macports.org/ticket/36438
        patchfiles-append   ${perl5.major}/fix-miniperl-linking-PR36438.patch

        # Install files under 5.xx rather than 5.xx.yy
        # https://trac.macports.org/ticket/43480
        patchfiles-append   ${perl5.major}/install-under-short-version-PR43480.patch

        if {${perl5.major} == 5.16} {
            patchfiles-append \
                            ${perl5.major}/use-stdbool.patch
            # Avoid a C++ linkage trick that recent Clang doesn't like. See #43150
            # and https://rt.perl.org/Public/Bug/Display.html?id=121714.
            patchfiles-append \
                            ${perl5.major}/fix-cxx-dNOOP-PR43150.patch
        }
        if {${perl5.major} >= 5.22 && ${perl5.major} <= 5.24} {
            # failed test
            # https://trac.macports.org/ticket/51327
            patchfiles-append \
                            ${perl5.major}/patch-dist-IO-t-cachepropagate-unix.t.diff
        }
        if {${perl5.major} == 5.24} {
            patchfiles-append \
                            ${perl5.major}/fix-ld-modification.patch
        }
        if {${perl5.major} < 5.24} {
            # Do not compile for 10.3/10.4
            # https://trac.macports.org/ticket/51980
            patchfiles-append \
                            ${perl5.major}/remove-10.3-target-PR126360.patch
        }
        if {${perl5.major} >= 5.24 && ${perl5.major} < 5.28} {
            # Fix library path (backported)
            # https://rt.perl.org/Public/Bug/Display.html?id=126706
            patchfiles-append \
                            ${perl5.major}/adjust-dependency-paths-PR126706.patch
        }
        if {${perl5.major} == 5.26} {
            # Avoid rebuilding DB_File in the destroot phase
            patchfiles-append \
                            ${perl5.major}/make_ext.pl-version.patch
        }
        if {${perl5.major} >= 5.26} {
            # enable syscall() on Sierra for compatibility with earlier OS versions and perl5.24
            # Apple has deprecated syscall() on Sierra but it is still available
            patchfiles-append \
                            ${perl5.major}/enable-syscall-on-sierra.patch
        }
        if {${perl5.major} == 5.28} {
            # Fix build failure when parent paths are not completely accessible.
            # https://github.com/perl/perl5/issues/16903#issuecomment-544100709
            patchfiles-append \
                            ${perl5.major}/add-internals-getcwd.patch \
                            ${perl5.major}/dont-write-invalid-write_buildcustomize.pl.patch \
                            ${perl5.major}/fallback-to-built-in-getcwd.patch \
        }
        if {${perl5.major} >= 5.28 && ${perl5.major} <= 5.30} {
            ## backport the fix for "macOS 11.x" that went into 5.32.1
            ## see https://github.com/Perl/perl5/pull/17946
            patchfiles-append \
                            ${perl5.major}/patch-hints-darwin_sh.diff \
        }
        if {${perl5.major} >= 5.34} {
            # Do not suppress errors for implicit function declarations
            # https://trac.macports.org/ticket/63022
            patchfiles-append \
                            ${perl5.major}/patch-want-implicit-errors.diff
        }
        if {${perl5.major} >= 5.36} {
            # Do not override deployment target
            # https://trac.macports.org/ticket/71152
            patchfiles-append \
                            ${perl5.major}/remove-deployment-target-override.diff
        }

        post-patch {
            reinplace -W ${worksrcpath} "s|__PREFIX__|${prefix}|g" \
                    Configure Makefile.SH cpan/DB_File/config.in
        }

        # Rather not revbump many p5 ports, so just fix it for new versions
        set man1ext 1pm
        if {${perl5.major} >= 5.38} {
            set man1ext 1
        }

        configure.ccache    no
        configure.distcc    no
        configure.env       LC_ALL=C
        configure.cmd       sh Configure
        configure.pre_args
        configure.universal_args-delete \
                            --disable-dependency-tracking
        configure.post_args -des \
                            -Dprefix='${prefix}' \
                            -Dscriptdir='${prefix}/bin' \
                            -Dvendorprefix='${prefix}' \
                            -Dusemultiplicity=y \
                            -Dusethreads \
                            -Duseshrplib \
                           {-Dcc="$CC"} \
                            -Dman1ext=${man1ext} \
                            -Dman3ext=3pm \
                            -Dinstallstyle='lib/perl5' \
                            -Dman1dir='${prefix}/share/man/man1' \
                            -Dman3dir='${prefix}/share/man/man3' \
                            -Dsitebin='${prefix}/libexec/perl${perl5.major}/sitebin' \
                            -Dsiteman1dir='${prefix}/share/perl${perl5.major}/siteman/man1' \
                            -Dsiteman3dir='${prefix}/share/perl${perl5.major}/siteman/man3' \
                            -Dvendorbin='${prefix}/libexec/perl${perl5.major}' \
                            -Dvendorman1dir='${prefix}/share/perl${perl5.major}/man/man1' \
                            -Dvendorman3dir='${prefix}/share/perl${perl5.major}/man/man3' \
                            -Dpager='/usr/bin/less -sR' \
                            -Dperlpath="${perl5.bin}" \
                            -Dstartperl="#!${perl5.bin}" \
                           {-Acppflags="$CPPFLAGS"} \
                           {-Accflags="$CFLAGS"} \
                           {-Alddlflags="$LDFLAGS"} \
                           {-Aldflags="$LDFLAGS"}

        ## perl5.28 and 5.30 will compile on macOS 11.3 / Xcode 12.5 with
        ##   the above patch-hints-darwin_sh.diff, and perl5.32(.1) has
        ##   the fix in that patch included.  So only use the below
        ##   work-around for "buggy configure scripts" for perl < 5.28
        if {${perl5.major} < 5.28} {
            # Workaround buggy configure scripts that expect 10.x
            if {[vercmp ${macosx_deployment_target} 11.0] >= 0} {
                macosx_deployment_target 10.16
            }
            if {${os.major} >= 20} {
                configure.env-append SYSTEM_VERSION_COMPAT=1
            }
        }

        # https://trac.macports.org/ticket/66478
        if {${perl5.major} < 5.28} {
            platforms           {darwin < 22} freebsd linux
        }

        post-configure {
            if {[variant_exists universal] && [variant_isset universal]} {
                system "cd ${worksrcpath} && ed - ${worksrcpath}/config.h < ${filespath}/${perl5.major}/config.h.ed"
            }
        }

        post-build {
            # preserve file mtimes to avoid rebuilding
            set mtime_files [list config.h lib/Config_heavy.pl lib/Config.pm]
            foreach f $mtime_files {
                set oldmtimes($f) [file mtime ${worksrcpath}/${f}]
            }

            reinplace -E {s/-arch [a-z0-9_]+//g} \
                ${worksrcpath}/lib/Config_heavy.pl
            reinplace -E {s/-mmacosx-version-min=[0-9.]+//g} \
                ${worksrcpath}/lib/Config_heavy.pl
            reinplace "s|${configure.cc}|/usr/bin/cc|g" \
                ${worksrcpath}/lib/Config.pm \
                ${worksrcpath}/lib/Config_heavy.pl \
                ${worksrcpath}/config.h
            reinplace -E {s|-isysroot[[:space:]]*[^[:space:]]+\.sdk||g} \
                ${worksrcpath}/lib/Config_heavy.pl \
                ${worksrcpath}/config.h
            reinplace -E {s|-Wl,-syslibroot,[^[:space:]]+\.sdk||g} \
                ${worksrcpath}/lib/Config_heavy.pl

            foreach f $mtime_files {
                file mtime ${worksrcpath}/${f} $oldmtimes($f)
            }
        }

        test.run            yes

        variant dtrace description {Build with DTrace probes} {
            configure.args-append   -Dusedtrace
        }

        post-destroot {
            # avoid conflicting with other perl versions
            # perl5 creates unversioned symlinks
            delete ${destroot}${prefix}/bin/perl
            foreach binFile [glob -directory "${destroot}${prefix}/bin" *] {
                if {$binFile ne "${destroot}${prefix}/bin/perl${version}"} {
                    move ${binFile} ${binFile}-${perl5.major}
                }
            }
            move ${destroot}${prefix}/bin/perl${version} ${destroot}${prefix}/bin/${subport}
            ln -s ${subport} ${destroot}${prefix}/bin/perl${version}
            foreach man1File [glob -directory "${destroot}${prefix}/share/man/man1" *] {
                regexp (.*)(\.1.*) ${man1File} -> program suffix
                move ${man1File} ${program}-${perl5.major}.1
            }
            foreach man3File [glob -directory "${destroot}${prefix}/share/man/man3" *] {
                regexp (.*)(\.3.*) ${man3File} -> program suffix
                move ${man3File} ${program}-${perl5.major}${suffix}
            }
        }

        livecheck.type      regex
        livecheck.url       https://www.cpan.org/src
        livecheck.regex     perl-(5\\.${minor}\\.\\d)\\.
    }
}

# wrapper port
if {$subport eq $name} {
    description             Wrapper port for Perl 5.x
    long_description        ${description}

    supported_archs         noarch
    platforms               any
    configure.cxx_stdlib

    perl5.require_variant   yes
    perl5.conflict_variants yes
    perl5.branches          5.34 5.36 5.38
    perl5.default_branch    5.34
    perl5.create_variants   ${perl5.branches}

    distfiles
    use_configure           no
    build                   {}

    ##
    ## Note:  the destroot section below currently uses lists of files
    ##   to know what files to link.  In the future we can use
    ##   something like:
    ##     set contents_list [registry_port_registered $portname])
    ##   to get the lists of binaries and man pages installed by
    ##   the perl5.x ports.
    ##
    destroot {
        if {[file exists ${perl5.bin}]} {
            ln -s perl${perl5.major} ${destroot}${prefix}/bin/${name}
            ln -s perl${perl5.major} ${destroot}${prefix}/bin/perl
        } else {
            ui_error "Can't find perl ${perl5.major} (as ${perl5.bin}) so can't link $name to it."
            return -code error "perl${perl5.major} is missing"
        }
        # some binaries are not included in the list because they would conflict
        # with module ports:
        # config_data    -> p5-module-build (ticket #24025)
        # corelist       -> p5-module-corelist (ticket #28485)
        # instmodsh      -> p5-extutils-makemaker (ticket #24590)
        # ptar, ptardiff -> p5-archive-tar (ticket #28255)
        # shasum         -> p5-digest-sha (ticket #28580)
        foreach list {binList man1List man3List} {
            set fd [open ${filespath}/${list}]; set $list [read $fd]; close $fd
        }
        foreach binFile $binList {
            if {[file exists ${prefix}/bin/${binFile}-${perl5.major}]} {
                ln -s ${binFile}-${perl5.major} ${destroot}${prefix}/bin/${binFile}
            }
        }
        file mkdir ${destroot}${prefix}/share/man/man1
        foreach manFile $man1List {
            if {[file exists ${prefix}/share/man/man1/${manFile}-${perl5.major}.1.gz]} {
                ln -s ${manFile}-${perl5.major}.1.gz ${destroot}${prefix}/share/man/man1/${manFile}.1.gz
            }
        }
        file mkdir ${destroot}${prefix}/share/man/man3
        foreach manFile $man3List {
            if {[file exists ${prefix}/share/man/man3/${manFile}-${perl5.major}.3pm.gz]} {
                ln -s ${manFile}-${perl5.major}.3pm.gz ${destroot}${prefix}/share/man/man3/${manFile}.3pm.gz
            }
        }
    }

    livecheck.type      none
}
