# -*- 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               legacysupport 1.1

configure.cxx_stdlib    libc++
compiler.cxx_standard   2020

name                    nodejs24
version                 24.7.0
revision                0

categories              lang net
license                 {MIT BSD}
maintainers             {ciserlohn @ci42} openmaintainer

# Attempting to use node on Mac OS X 10.7 causes a kernel panic. libuv could
# be patched to fix this; see https://trac.macports.org/ticket/71475
platforms               {darwin != 11.*}

description             Evented I/O for V8 JavaScript

long_description        Node's goal is to provide an easy way to build scalable network programs in JavaScript. \
                        Node is similar in design to and influenced by systems like Ruby's Event \
                        Machine or Python's Twisted. Node takes the event model a bit further-it \
                        presents the event loop as a language construct instead of as a library.

conflicts               nodejs8 nodejs10 nodejs12 nodejs14 nodejs16 nodejs18 nodejs20 nodejs22

homepage                https://nodejs.org/
master_sites            ${homepage}dist/v${version}
use_xz                  yes

checksums               rmd160  198943fe13474f78e5417ca4186f3e50e67fa86d \
                        sha256  cf74a77753b629ffebd2e38fb153a21001b2b7a3c365c0ec7332b120b98c7251 \
                        size    51707840

distname                node-v${version}

set py_ver              3.13
set py_ver_nodot        [string map {. {}} ${py_ver}]

depends_build-append    port:pkgconfig \
                        port:python${py_ver_nodot}

depends_lib-append      path:lib/pkgconfig/icu-uc.pc:icu \
                        port:zlib

# The Node.js docs says it requires "Xcode >= 13 (Apple LLVM >= 12)" [1]
# and accordingly the compile fails on macOS 11.7 Big Sur with Xcode's
# clang. However, bumping the requirement for clang 1400 or greater
# gets it to successfully compile.
# [1] https://github.com/nodejs/node/blob/v24.x/BUILDING.md#supported-toolchains
compiler.blacklist-append {clang < 1400}

# use the system libuv instead of the bundled version, as it is fixed for older systems
if { ${os.platform} eq "darwin" && ${os.major} < 15 } {
    # for older macs it seems nodejs20+ requires the packaged libuv,
    # unlike earlier versions. the flag below ensures the libuv
    # packaged with nodejs20+ can be used
    if {[string match *clang* ${configure.compiler}]} {
        configure.cxx-append      -Wno-error=incompatible-function-pointer-types
    }

    if {${configure.cxx_stdlib} eq "libc++"} {
        depends_lib-append        port:macports-libcxx
        configure.cxx-append      -Wl,-L${prefix}/lib/libcxx
    }

    #we guard against using the pthread qos API for Yosemite (10.10) and lower,
    #since it is not available.
    if { ${os.major} < 14 } {
        configure.cppflags-append -DNOT_ON_BROSEMITE_OR_LATER=1
    }
}

# suppress a warning-as-error that shows up with newer clang compilers
if {[string match *clang* ${configure.compiler}]} {
    configure.cxx-append      -Wno-error=enum-constexpr-conversion

    #the ventura buildbot will fail because it doesn't recognise this flag
    #so we disable unknown warnings as errors for older compilers
    configure.cxx-append      -Wno-error=unknown-warning-option
}

proc rec_glob {basedir pattern} {
    set files [glob -directory $basedir -nocomplain -type f $pattern]
    foreach dir [glob -directory $basedir -nocomplain -type d *] {
        lappend files {*}[rec_glob $dir $pattern]
    }
    return $files
}

configure.python        ${prefix}/bin/python${py_ver}

patchfiles              patch-common.gypi.diff \
                        patch-add-pthread-qos-guard-for-older-macs.patch

post-patch {
    foreach f [concat ${worksrcpath}/configure \
                   ${worksrcpath}/tools/gyp/gyp \
                   ${worksrcpath}/deps/v8/tools/objdump-v8 \
                   [rec_glob ${worksrcpath} *.py]] {
        reinplace -q "s|/usr/bin/env python3|${configure.python}|" ${f}
        reinplace -q "s|/usr/bin/env python|${configure.python}|" ${f}
    }
    foreach gypfile [rec_glob ${worksrcpath} *.gyp*] {
        reinplace -q "s|'python3'|'${configure.python}'|" ${gypfile}
        reinplace -q "s|'python'|'${configure.python}'|" ${gypfile}
    }
    if { ${os.platform} eq "darwin" && ${os.major} <= 17 } {
        # Officially nodejs requires Xcode 11 to compile, however, the
        # only item that Xcode 11 has that Xcode 10.1 doesn't is
        # os/signpost.h, so disable system instrumentation which uses
        # it. This provides support for macOS 10.13 which can only use
        # Xcode 10.1.
        reinplace -q "s|'v8_enable_system_instrumentation': 1|'v8_enable_system_instrumentation': 0|" ${worksrcpath}/tools/v8_gypfiles/features.gypi
    }
}

pre-configure {
    # Copy zlib headers here because we do not want to prepend the entire
    # ${prefix}/include to the include path (the build will then attempt to use
    # ICU headers)
    file mkdir ${workpath}/zlib-inc
    file copy ${prefix}/include/zconf.h ${prefix}/include/zlib.h \
        ${workpath}/zlib-inc/
}

configure.args-append   --without-npm
configure.args-append   --with-intl=system-icu
configure.args-append   --shared-zlib
configure.args-append   --shared-zlib-includes=${workpath}/zlib-inc
configure.args-append   --shared-zlib-libpath=${prefix}/lib

# V8 only supports ARM and IA-32 processors
supported_archs         i386 x86_64 arm64

universal_variant       no

# https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V17.md#openssl-30
variant no_openssl3_with_quic description {use MacPort's OpenSSL rather than Node.js' provided OpenSSL 3.0 extended with QUIC} {
    depends_lib-append      port:openssl3
    configure.args-append   --shared-openssl
    configure.args-append   --shared-openssl-includes=${prefix}/libexec/openssl3/include/openssl
    configure.args-append   --shared-openssl-libpath=${prefix}/libexec/openssl3/lib
}

# "V8 doesn't like cache."
configure.ccache        no

test.run                yes
test.cmd                ${build.cmd} -j${build.jobs}

switch $build_arch {
    i386 {
        configure.args-append   --dest-cpu=ia32
    }
    x86_64 {
        configure.args-append   --dest-cpu=x64
    }
   arm64 {
        configure.args-append   --dest-cpu=arm64
    }
}

build.args-append   CC=${configure.cc} \
                    CXX=${configure.cxx} \
                    CXX.host=${configure.cxx} \
                    CPP=${configure.cpp} \
                    CPPFLAGS="${configure.cppflags}" \
                    CFLAGS="${configure.cflags} ${configure.cppflags}" \
                    CXXFLAGS="${configure.cxxflags} ${configure.cppflags}" \
                    LDFLAGS="${configure.ldflags} [legacysupport::get_library_link_flags]" \
                    PYTHON=${configure.python} \
                    V=1

destroot {
    set bindir ${destroot}${prefix}/bin
    set libdir ${destroot}${prefix}/lib
    set libndir ${libdir}/node
    set libddir ${libdir}/dtrace
    set incdir ${destroot}${prefix}/include/node
    set docdir ${destroot}${prefix}/share/doc/${name}

    xinstall -d ${bindir}
    xinstall -d ${libdir}
    xinstall -d ${libndir}
    xinstall -d ${libddir}
    xinstall -d ${incdir}
    xinstall -d ${incdir}/uv
    xinstall -d ${docdir}

    # install binaries
    xinstall -m 755 -W ${worksrcpath} \
        out/Release/node \
        ${bindir}

    # install headers
    xinstall -m 644 {*}[glob ${worksrcpath}/src/*.h]                ${incdir}
    xinstall -m 644 {*}[glob ${worksrcpath}/deps/v8/include/*.h]    ${incdir}
    xinstall -m 644 {*}[glob ${worksrcpath}/deps/uv/include/*.h]    ${incdir}
    xinstall -m 644 {*}[glob ${worksrcpath}/deps/uv/include/uv/*.h] ${incdir}/uv
    xinstall -m 644 {*}[glob ${worksrcpath}/deps/cares/include/*.h] ${incdir}

    # install manpage
    xinstall -m 644 -W ${worksrcpath} \
        doc/node.1 \
        ${destroot}${prefix}/share/man/man1

    # install docs
    xinstall -m 644 -W ${worksrcpath} \
        CHANGELOG.md \
        CONTRIBUTING.md \
        GOVERNANCE.md \
        LICENSE \
        README.md \
        SECURITY.md \
        ${docdir}
}

livecheck.url       ${homepage}dist/
livecheck.type      regex
livecheck.regex     {v(24\.\d+\.\d+)}
