# -*- 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
PortGroup           select 1.0
PortGroup           clang_dependency 1.0

name                python27
epoch               2
# Remember to keep py27-tkinter and py27-gdbm's versions sync'd with this
version             2.7.18
revision            10

set major           [lindex [split $version .] 0]
set branch          [join [lrange [split ${version} .] 0 1] .]
categories          lang
license             PSF

maintainers         {jmr @jmroot} openmaintainer

description         An interpreted, object-oriented programming language
long_description    Python is an interpreted, interactive, object-oriented \
                    programming language.

homepage            https://www.python.org/
master_sites        ${homepage}ftp/python/${version}/

distname            Python-${version}
if {$subport eq $name} {
use_xz              yes
}

checksums           md5     fd6cc8ec0a78c44036f825e739f36e5a \
                    rmd160  40a514bb05c9e631454ea8466e28f5bb229428ad \
                    sha256  b62c0e7937551d0cc02b8fd5cb0f544f9405bafc9a54d3808ed4594812edef43 \
                    size    12854736

patchfiles          patch-Makefile.pre.in.diff \
                    patch-setup.py.diff \
                    patch-Lib-cgi.py.diff \
                    patch-Lib-ctypes-macholib-dyld.py.diff \
                    patch-configure.diff \
                    patch-libedit.diff \
                    enable-loadable-sqlite-extensions.patch \
                    patch-_osx_support.py.diff \
                    darwin20.diff \
                    arm.patch \
                    implicit.patch \
                    openssl_ver.patch \
                    libedit-types.patch

if {${os.platform} eq "darwin" && ${os.major} >= 21} {
    patchfiles-append patch-getpath.diff
}

if {${subport} eq ${name}} {
    PortGroup       openssl 1.0

    depends_build   path:bin/pkg-config:pkgconfig
    depends_lib     port:bzip2 \
                    port:db48 \
                    port:expat \
                    port:gettext-runtime \
                    port:libedit \
                    port:libffi \
                    port:ncurses \
                    port:sqlite3 \
                    port:zlib
    depends_run     port:python_select \
                    port:python2_select


    openssl.branch  1.1
}

# This port is used by clang-3.4 to bootstrap libcxx
subport ${name}-bootstrap {
    depends_extract         port:xz-bootstrap
    depends_skip_archcheck-append \
                            xz-bootstrap
    extract.suffix          .tar.xz
    extract.cmd             ${prefix}/libexec/xz-bootstrap/bin/xz

    prefix                  ${prefix}/libexec/${subport}
    set frameworks_dir      ${prefix}/Library/Frameworks
    set applications_dir    ${prefix}/Applications

    patchfiles-delete       patch-libedit.diff

    # Avoid macports-clang dep (doesn't use C++ anyway)
    configure.cxx_stdlib
    compiler.whitelist      clang llvm-gcc-4.2 gcc-4.2 apple-gcc-4.2

    # sterilize MacPorts build environment; we want nothing picked up from MP prefix
    compiler.cpath
    compiler.library_path

    configure.distcc        no

    # sterilize PATH
    configure.env-append    PATH=/usr/bin:/bin:/usr/sbin:/sbin
    build.env-append        PATH=/usr/bin:/bin:/usr/sbin:/sbin
}
# Also needed by later clangs.
if {${os.platform} eq "darwin" && ${os.major} < 11 && ${cxx_stdlib} eq "libc++"} {
    clang_dependency.extra_versions 3.7
}

configure.args-append \
                    --enable-framework=${frameworks_dir} \
                    --enable-ipv6
if {${subport} eq ${name} || ${os.platform} eq "darwin"} {
    # Non-darwin may not have a system libexpat or libffi, so we can't use them for the bootstrap port
    configure.args-append \
                    --with-system-expat \
                    --with-system-ffi
}

if {${subport} eq ${name}} {
    configure.cppflags-append -I${prefix}/include/db48
    configure.ldflags-append -L${prefix}/lib/db48

    # pkg-config removes -I flags for paths in CPATH, which confuses python.
    configure.env-append    PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1
}

configure.ccache    no

post-patch {
    reinplace "s|@@PREFIX@@|${prefix}|g" \
        ${worksrcpath}/Lib/cgi.py \
        ${worksrcpath}/Lib/ctypes/macholib/dyld.py
    reinplace "s|@@APPLICATIONS_DIR@@|${applications_dir}|" \
        ${worksrcpath}/configure
}

post-configure {
    set oldmtime [file mtime ${worksrcpath}/pyconfig.h]
    reinplace "s;/* #undef PY_FORMAT_LONG_LONG */;#define PY_FORMAT_LONG_LONG \"ll\";" ${worksrcpath}/pyconfig.h
    file mtime ${worksrcpath}/pyconfig.h $oldmtime
}

build.target        all

test.run            yes
test.target         test

destroot.target     frameworkinstall maninstall

if {$subport eq $name} {
set pythonNoDot python[string map {. {}} $branch]
select.entries      [list python python-$pythonNoDot $pythonNoDot] \
                    [list python2 python2-$pythonNoDot $pythonNoDot]

notes "
To make this the default Python or Python 2 (i.e., the version run by\
the 'python' or 'python2' commands), run one or both of:

    sudo port select --set python $pythonNoDot
    sudo port select --set python2 $pythonNoDot
"
}

platform darwin {
    set framewpath ${frameworks_dir}/Python.framework
    set framewdir  ${framewpath}/Versions/${branch}

    post-patch {
        if {![file exists /usr/lib/libSystemStubs.a]} {
            reinplace s/-lSystemStubs//g ${worksrcpath}/configure
        }
    }

    post-configure {
        # poll() misbehaves on 10.8 and older
        # See https://trac.macports.org/ticket/18376
        if {${os.major} <= 12} {
            set oldmtime [file mtime ${worksrcpath}/pyconfig.h]
            system -W ${worksrcpath} "ed - pyconfig.h < ${filespath}/pyconfig.ed"
            file mtime ${worksrcpath}/pyconfig.h $oldmtime
        }
    }

    post-destroot {
        foreach dir { Headers Resources Python Versions/Current } {
            file delete ${destroot}${framewpath}/${dir}
        }

        ln -s ${framewdir}/share/man/man1/python${branch}.1 ${destroot}${prefix}/share/man/man1/
        ln -s ${framewdir}/Python ${destroot}${prefix}/lib/libpython${branch}.dylib
        ln -s ${framewdir}/lib/pkgconfig/python-${branch}.pc ${destroot}${prefix}/lib/pkgconfig/

        set libdir ${destroot}${framewdir}/lib/python${branch}
        # change LINKFORSHARED to support dependents that incorrectly use it
        system -W ${libdir} "awk -F : \
            \"/'LINKFORSHARED'/ {printf \\\"%s: '-L${framewdir}/lib/python${branch}/config\
            -lpython${branch} -ldl -framework CoreFoundation',\\n\\\", \\\$1; next} {print}\"\
            _sysconfigdata.py > _sysconfigdata.py.new"
        file rename -force ${libdir}/_sysconfigdata.py.new \
            ${libdir}/_sysconfigdata.py

        # remove -arch flags from the config
        reinplace -E {s|-arch [a-z0-9_]+||g} \
            ${libdir}/_sysconfigdata.py

        # recompile the modified file
        set python_for_build python.exe
        # executable differs depending on filesystem case sensitivity
        if {![file exists ${worksrcpath}/${python_for_build}]} {
            set python_for_build python
        }
        system -W ${worksrcpath} "env DYLD_FRAMEWORK_PATH=. ./${python_for_build} -E -m compileall -d [shellescape ${framewdir}/lib/python${branch}] [shellescape ${libdir}/_sysconfigdata.py]"
        system -W ${worksrcpath} "env DYLD_FRAMEWORK_PATH=. ./${python_for_build} -E -O -m compileall -d [shellescape ${framewdir}/lib/python${branch}] [shellescape ${libdir}/_sysconfigdata.py]"

        # Without this, LINKFORSHARED is set to
        # ... $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)
        # (this becomes Python.framework/Versions/2.7/Python) which doesn't
        # quite work (see ticket #15099); instead we mirror the behavior of
        # `python-config --ldflags` here.
        reinplace {s|^\(LINKFORSHARED=\).*$|\1 -L$(LIBPL) -lpython$(VERSION) $(LIBS) $(SYSLIBS)|} \
            ${libdir}/config/Makefile

        # remove -arch flags from the config
        reinplace -E {s|-arch [a-z0-9_]+||g} \
            ${libdir}/config/Makefile
    }
}

post-destroot {
    foreach unversionedFile {2to3 2to3-2 idle idle2 pydoc pydoc2 python python2 python-config python2-config pythonw pythonw2 smtpd.py smtpd2.py} {
        delete ${destroot}${prefix}/bin/${unversionedFile}
    }
}

variant universal {
    patchfiles-append patch-configure-universal.diff
    post-patch {
        reinplace \
            "s|__UNIVERSAL_ARCHFLAGS__|${configure.universal_cflags}|" \
            ${worksrcpath}/configure
    }
    configure.args-append   --enable-universalsdk=${configure.sysroot}
}

variant ucs4 description {Enable support for UCS4 (breaks ABI)} {
    configure.args-append   --enable-unicode=ucs4
    notes-append "The ucs4 variant changes Python's ABI, breaking binary\
    compatibility with extension modules. It is strongly recommended to\
    configure MacPorts to build all ports from source when using it. Adding\
    or removing this variant on an existing installation will mean that all\
    ports that install Python extension modules need to be reinstalled. This\
    variant also breaks compatibility with native Mac frameworks used by\
    modules such as PyObjC."
}

variant optimizations description {enable expensive, stable optimizations (including PGO)} {
    configure.args-append   --enable-optimizations
}

variant lto requires optimizations description {enable Link-Time Optimization} {
    configure.args-append   --with-lto
}

platform darwin {
    if {$subport ne "${name}-bootstrap"} {
        # Build failures on 10.9 and older
        if {${os.major} > 13} {
            default_variants    +lto +optimizations
        }
    }
}

livecheck.type          regex
livecheck.url           ${homepage}downloads/
livecheck.regex         Python (${branch}(?:\\.\\d+)*)
