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

# Upstream mldonkey does not build with OCaml 5:
#   https://github.com/ygrek/mldonkey/issues/120
# Luca Carlon's fork ports the code to OCaml 5, drops the autoconf/make
# build system in favour of dune and drops the GTK2 GUI (the web GUI is
# the only interface left). It has no releases of its own, so we follow
# the tip of its "dev" branch.
github.setup        carlonluca mldonkey e1953e5887a37c892551e25225c744437b666a91
version             3.2.1-20260502
revision            0
categories          net p2p
maintainers         nomaintainer
license             GPL-2+

description         Multi-network peer-to-peer daemon written in OCaml

long_description    MLdonkey is a multi-platform multi-network peer-to-peer \
                    client. It supports several large networks, such as \
                    eDonkey, Overnet, Bittorrent, Gnutella (Bearshare, \
                    Limewire, etc), Fasttrack (Kazaa, Imesh, Grobster) and \
                    Direct-Connect. Networks can be enabled/disabled, \
                    searches are performed in parallel on all enabled \
                    networks, but each file is only downloaded from one \
                    network, but from multiple clients concurrently. \
                    The daemon is controlled over telnet or its web GUI.

homepage            https://github.com/carlonluca/mldonkey

checksums           rmd160  c4833a8af9599bf7d8410d194bac4cbfb5a9bf10 \
                    sha256  3561d4ea88de3484f285fb5003fc33fea01c390f43a19b38fb820a84c985af09 \
                    size    3397429
github.tarball_from archive

# Version fed to autoconf.py, see post-configure below.
set mldonkey_semver 3.2.1

# NB: dune-project declares (lang dune 3.12), while port:ocaml-dune is
# pinned to 3.4.1 on darwin 8 and 9, where it fails with "Version 3.12 of
# the dune language is not supported". Those platforms need either a newer
# ocaml-dune or a lower (lang dune ...) upstream.
ocaml.build_type    dune

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

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

# camlp4 preprocesses options.ml4, gettext.ml4 and tools/ocamlpp/ocamlpp.ml4.
depends_build-append \
                    port:ocaml-camlp4 \
                    port:python${py_ver_nodot}

# OCaml libraries required by the dune files. Beware: ocaml-curl
# (ygrek/ocurl, findlib package "curl") does not exist in MacPorts yet
# and has to be added before this port can build.
depends_lib-append  port:ocaml-bitstring \
                    port:ocaml-camlp-streams \
                    port:ocaml-curl \
                    port:ocaml-num \
                    port:ocaml-syslog \
                    port:ocaml-uucp \
                    port:ocaml-uutf \
                    port:ocaml-xml-light

# C/C++ libraries linked into mlnet. Unlike the old autoconf build,
# nothing here is optional any more: the dune build compiles every stub
# unconditionally (see config/config.h in the distfile, which is now
# a static "everything is enabled" placeholder).
depends_lib-append  port:bzip2 \
                    port:curl \
                    port:gd2 \
                    port:libcryptopp \
                    port:libiconv \
                    path:include/turbojpeg.h:libjpeg-turbo \
                    port:libmagic \
                    port:libnatpmp \
                    port:libpng \
                    port:miniupnpc \
                    port:zlib

# Match the ocaml port. Note that dune compiles the C/C++ stubs with
# the compiler recorded in `ocamlc -config`, not with ${configure.cc}.
# And now we need C++11 anyway.
compiler.cxx_standard   2011

# autoconf.py derives the version from `git describe`, which is not
# available when building from a tarball; teach it to accept the version
# from the environment instead.
patchfiles-append   patch-autoconf.py.diff

# src/dune links the transitive static dependencies of curl (nghttp2,
# openssl, c-ares, brotli, zstd, idn2, unistring, psl) because upstream
# CI produces a fully static musl binary. We link shared libraries, so
# drop them; iconv, on the other hand, is not part of libc here.
patchfiles-append   patch-src-dune.diff

patchfiles-append   patch-cryptopp-cxx-flags.diff

# config/config.h is a hand-written placeholder describing a Linux/glibc
# host; disable the two defines which are wrong on Darwin.
patchfiles-append   patch-config-config.h.diff

# tar.mlcpp and misc2.mlcpp are preprocessed by a bare "cpp", which
# no environment variable reaches, so dune picks up /usr/bin/cpp –
# the Xcode gcc-4.2 driver, which chokes on "-x c" ("c: No such file or
# directory"). Make the program overridable and point it at the compiler
# MacPorts selected. The default stays "cpp" for upstream.
patchfiles-append   patch-mlcpp-preprocessor.diff

# dune compiles CryptoPP.cc with the *C* driver from `ocamlc -config` and
# links with it as well, so no C++ runtime ever reaches the link line.
# That goes unnoticed on Linux, where libcryptopp.so pulls in libstdc++
# via DT_NEEDED, but Darwin does not resolve symbols through indirect dylibs.
post-patch {
    if {${configure.cxx_stdlib} eq "libc++"} {
        set cxx_runtime -lc++
        set cxx_abi_flags -stdlib=libc++
    } else {
        set cxx_runtime -lstdc++
        # MacPorts' libstdc++ is built with the gcc4-compatible ABI, so
        # CryptoPP.cc must use the old std::string layout too; otherwise
        # its std::__cxx11 symbols do not resolve against libcryptopp.
        set cxx_abi_flags -D_GLIBCXX_USE_CXX11_ABI=0
    }
    reinplace "s|@CXXLIB@|${cxx_runtime}|" ${worksrcpath}/src/dune
    reinplace "s|@CXXABI@|${cxx_abi_flags}|" ${worksrcpath}/src/utils/lib/dune
}

dune.build.env-append \
                    MLDONKEY_CPP=${configure.cc}

# dune does not read ${configure.cflags} etc., but the C compiler it
# invokes honours CPATH and LIBRARY_PATH, which is how upstream CI builds
# on macOS. Use -append so the DUNE_CONFIG__COPY_FILE workaround which
# the PortGroup sets on darwin < 11 is preserved.
dune.build.env-append \
                    CPATH=${prefix}/include \
                    LIBRARY_PATH=${prefix}/lib

# The mlnet executable has no (public_name), so the @install alias which
# the PortGroup builds by default is empty. Build the binary directly and
# do not restrict dune to the "mldonkey" package.
dune.packages
dune.build.target   src/mlnet.exe

# Generate src/utils/lib/autoconf.ml, which the "autoconf" dune library
# is built from. This replaces the old ./configure run.
post-configure {
    system -W ${worksrcpath} "MLDONKEY_VERSION=${mldonkey_semver} \
        MLDONKEY_SCM_VERSION=${mldonkey_semver}-0-g[string range ${github.version} 0 6] \
        ${configure.python} autoconf.py"
}

# dune installs nothing useful (the only public_name in the tree is
# the "mldonkey.io" library), so install by hand. On hosts where OCaml
# has no native backend dune still produces src/mlnet.exe, linked as
# a custom bytecode runtime, hence no separate .byte case any more.
destroot {
    xinstall -d ${destroot}${prefix}/bin
    xinstall -m 0755 ${worksrcpath}/_build/default/src/mlnet.exe \
        ${destroot}${prefix}/bin/mlnet

    set docdir ${prefix}/share/doc/${name}
    xinstall -d ${destroot}${docdir}
    copy ${worksrcpath}/docs ${destroot}${docdir}/
    xinstall -m 0644 -W ${worksrcpath} CHANGES.md Copying.txt Developers.txt \
        README.md ${destroot}${docdir}/
}

# Branch snapshot, no releases upstream.
livecheck.type      none
