# -*- 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               github 1.0
PortGroup               cmake 1.1
PortGroup               legacysupport 1.1
PortGroup               active_variants 1.1

# llama.cpp and ggml must be updated in sync
github.setup            ggerganov llama.cpp 0.4.0 v
github.tarball_from     archive
revision                0
categories              llm
maintainers             {i0ntempest @i0ntempest} openmaintainer
license                 MIT

description             LLM inference in C/C++
long_description        The main goal of ${name} is to enable LLM inference with minimal\
                        setup and state-of-the-art performance on a wide variety of hardware\
                         - locally and in the cloud.

set source_distfile     ${distfiles}
set nightly_tag_distfile \
                        nightly-tag-${version}.txt
master_sites-append     https://github.com/ggml-org/llama.cpp/releases/download/v${version}/nightly-tag.txt?dummy=:nightly_tag
distfiles-append        ${nightly_tag_distfile}:nightly_tag

checksums               ${source_distfile} \
                        rmd160  f9270dbc24f048cde4d6054dbdd4cddc15f7dab7 \
                        sha256  9c2948aa9c79c92dd0e4c98e11ff5cf76dfdcaebdeb18e3e93409e9a98aefdab \
                        size    37288249 \
                        ${nightly_tag_distfile} \
                        rmd160  0ccb87e688457ad203d4f4e71c984083d8f7b22a \
                        sha256  bd0afc13ffe4aaa2f02eb7df8882a2617907d7f232012ae2ca0f21f6b865fbe0 \
                        size    7

extract.only            ${source_distfile}

# error: 'filesystem' file not found on 10.14
legacysupport.newest_darwin_requires_legacy \
                        18
legacysupport.use_mp_libcxx \
                        yes

depends_build-append    path:bin/pkg-config:pkgconfig

depends_lib-append      port:curl \
                        port:ggml

compiler.cxx_standard   2017

# cmake relies on git for version info. We need to set them manually.
configure.args-append   -DLLAMA_CURL=ON \
                        -DLLAMA_BUILD_IS_DEV=OFF \
                        -DLLAMA_BUILD_TESTS=OFF \
                        -DLLAMA_USE_SYSTEM_GGML=ON

pre-configure {
    set fd [open ${distpath}/${nightly_tag_distfile} r]
    set nightly_tag [string trim [read ${fd}]]
    close ${fd}

    if {![regexp {^b([0-9]+)$} ${nightly_tag} -> llama_build_number]} {
        return -code error \
            "Invalid llama.cpp nightly tag: ${nightly_tag}"
    }

    set git-commit [exec curl -fsSL \
                        -H "Accept: application/vnd.github.sha" \
                        https://api.github.com/repos/ggml-org/llama.cpp/commits/${github.tag_prefix}${version} | \
                        cut -c1-7]

    configure.args-append \
        -DLLAMA_BUILD_COMMIT=${git-commit} \
        -DLLAMA_BUILD_NUMBER=${llama_build_number}
}

# Proxy dependency variants keep llama.cpp and ggml backend variants in sync.
variant blas description {Use ggml with BLAS support} {
    require_active_variants ggml blas
}

variant openmp description {Use ggml with OpenMP support} {
    require_active_variants ggml openmp
}

variant native description {Use ggml optimized for the build host CPU} {
    require_active_variants ggml native
}

variant opencl description {Use ggml with OpenCL support} {
    require_active_variants ggml opencl
}

variant metal conflicts vulkan description {Use ggml with Metal support} {
    require_active_variants ggml metal
}

variant vulkan conflicts metal description {Use ggml with Vulkan support} {
    require_active_variants ggml vulkan
}

default_variants        +blas +openmp

# Newer Metal APIs used by ggml are unavailable with the 10.14 SDK.
if {${os.platform} eq "darwin" && ${os.subplatform} eq "macosx" && \
    (${os.major} >= 20 && ${configure.sdk_version} >= 11)} {
    default_variants    +metal
}

set ::python_branch     3.14
set ::python_version    [string map {. ""} ${::python_branch}]

variant model_converters description {install extra model conversion Python scripts} {
    depends_run-append  port:python${::python_version} \
                        port:py${::python_version}-numpy \
                        port:py${::python_version}-pytorch \
                        port:py${::python_version}-transformers \
                        port:py${::python_version}-mistral-common

    post-patch {
        reinplace "s|!/usr/bin/env python3|!${prefix}/bin/python${::python_branch}|" \
            ${worksrcpath}/conversion/base.py \
            {*}[glob ${worksrcpath}/convert*.py] \
            {*}[glob ${worksrcpath}/gguf-py/gguf/scripts/*.py]
    }

    post-destroot {
        xinstall -d ${destroot}${prefix}/libexec/${name}
        xinstall -m 755 {*}[glob ${worksrcpath}/convert*.py] ${destroot}${prefix}/libexec/${name}/
        copy ${worksrcpath}/conversion ${worksrcpath}/gguf-py ${destroot}${prefix}/libexec/${name}/
        delete {*}[glob ${destroot}${prefix}/libexec/${name}/*_update.py]
        foreach file {LICENSE examples tests} {
            delete ${destroot}${prefix}/libexec/${name}/gguf-py/${file}
        }
        if {![variant_isset gui]} {
            delete {*}[glob ${destroot}${prefix}/libexec/${name}/gguf-py/gguf/scripts/*gui.py]
        }
        foreach file [concat \
            [glob -directory ${destroot}${prefix}/libexec/${name} *.py] \
            [glob -directory ${destroot}${prefix}/libexec/${name}/gguf-py/gguf/scripts/ *.py] \
        ] {
            set filebasename [file rootname [file tail $file]]
            set launcher ${destroot}${prefix}/bin/[lindex [split ${name} .] 0]-[string map {_ -} ${filebasename}]
            set target [string replace ${file} 0 [string length ${destroot}]-1]
            ui_debug "Creating launcher: ${launcher} => ${target}"
            set fh [open ${launcher} w]
            puts ${fh} "#!/bin/sh"
            puts ${fh} "exec ${target} \"\$@\""
            close ${fh}
            file attributes ${launcher} -permissions 0755
        }
    }
}

variant gui requires model_converters description {install the Qt-based gguf-editor-gui script} {
    depends_run-append  port:py${::python_version}-pyside6
}

livecheck.type          regex
livecheck.url           https://api.github.com/repos/ggml-org/llama.cpp/releases/latest
livecheck.regex         {"tag_name": "v([0-9.]+)"}
