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

# clock_gettime needed for abseil
# https://github.com/macports/macports-ports/pull/19905#issuecomment-1680281240
legacysupport.newest_darwin_requires_legacy 15

# NOTE: For a minor or major version number change, also
# revbump et, protobuf-c, mosh and py-onnx.

# FIXME: 33.0+ is broken: https://github.com/protocolbuffers/protobuf/issues/24158

github.setup    protocolbuffers protobuf 35.1 v
git.branch      v${version}
revision        0
categories      devel
license         BSD
maintainers     {mascguy @mascguy} openmaintainer

description     Encode data in an efficient yet extensible format
long_description \
                Google Protocol Buffers are a flexible, efficient, \
                automated mechanism for serializing structured data – \
                think XML, but smaller, faster and simpler. You \
                define how you want your data to be structured once, \
                then you can use special generated source code to \
                easily write and read your structured data to and from \
                a variety of data streams and using a variety of \
                languages. You can even update your data structure \
                without breaking deployed programs that are compiled \
                against the "old" format. You specify how you want \
                the information you're serializing to be structured by \
                defining protocol buffer message types in .proto \
                files. Each protocol buffer message is a small \
                logical record of information, containing a series \
                of name-value pairs.
homepage        https://protobuf.dev

checksums       rmd160  df6d51d81c14aade097e9745536adbe008de695d \
                sha256  f0b6838e7522a8da96126d487068c959bc624926368f3024ac8fd03abd0a1ac4 \
                size    7146181
github.tarball_from releases

worksrcdir      protobuf-${version}

# Upstream adds zlib include - which is ${prefix}/include - before search path
# of 3rd-party components, like gtest, gmock etc. That causes the external
# versions of those to be pulled in, and the build fails.
# So don't let the project cmake add zlib; already added (last) by base.
patchfiles-append   cmake-zlib-include.diff

# Needed for 31.x and 32.x, merged later:
# patchfiles-append   patch-fix-bools.diff

# Needed for 33.x, not needed for 35.x (merged):
# patchfiles-append   patch-fix-endian.diff

# Still needed for 35.x:
patchfiles-append   patch-boolkeys.diff

# Needed for 35.x (new regression):
patchfiles-append   patch-fix-parse_context.h.diff

# Minimum standard:
compiler.cxx_standard   2017

compiler.thread_local_storage   yes
# error: constexpr constructor never produces a constant expression [-Winvalid-constexpr]
compiler.blacklist-append \
                {clang < 900}

if {[string match *clang* ${configure.compiler}]} {
    # Quiet deprecation warnings
    configure.cxxflags-append \
                -Wno-deprecated-declarations \
                -Wno-error=unknown-warning-option \
                -Wno-unknown-warning-option
}

# https://github.com/protocolbuffers/protobuf/issues/21814
if {[string match *gcc* ${configure.compiler}] && ${configure.build_arch} in [list arm i386 ppc]} {
    configure.ldflags-append \
                -latomic
}

# Clear optflags; controlled by project, via cmake build type
configure.optflags

if {[variant_isset debug]} {
    cmake.build_type Debug
} else {
    cmake.build_type RelWithDebInfo
}

depends_lib-append \
                port:abseil \
                port:zlib

configure.args-append \
                -DBUILD_SHARED_LIBS:BOOL=ON \
                -Dprotobuf_ABSL_PROVIDER=package \
                -Dprotobuf_BUILD_LIBPROTOC:BOOL=ON \
                -Dprotobuf_BUILD_PROTOC_BINARIES:BOOL=ON \
                -Dprotobuf_BUILD_TESTS:BOOL=OFF

post-destroot {
    set docdir ${destroot}${prefix}/share/doc/${name}

    xinstall -d ${docdir}

    foreach f {CONTRIBUTING.md CONTRIBUTORS.txt LICENSE README.md SECURITY.md editors examples} {
        copy ${worksrcpath}/${f} ${docdir}
    }
}

proc port_test_ver_check {p_name p_ver p_rev} {
    if {[catch {set port_ver_info [lindex [registry_active ${p_name}] 0]}]} {
        error "Tests require that ${p_name} be active; install, then re-run tests"
    } else {
        set test_ver ${p_ver}_${p_rev}
        set port_ver [lindex ${port_ver_info} 1]_[lindex ${port_ver_info} 2]
        ui_info "port_test_ver_check: ${p_name}: test_ver: ${test_ver}; port_ver: ${port_ver}"

        if {[vercmp ${port_ver} ${test_ver}] != 0} {
            error "Tests require installed version of ${p_name} to match port; update, then re-run tests"
        }
    }
}

post-destroot {
    # Same condition as in legacysupport:
    if {${os.platform} eq "darwin" && ${configure.cxx_stdlib} ne "libc++"} {
        foreach exe {protoc protoc-gen-upb protoc-gen-upb_minitable protoc-gen-upbdefs} {
            # Delete symlinks:
            delete ${destroot}${prefix}/bin/${exe}
            # Use our wrappers instead:
            xinstall -m 0755 ${filespath}/${exe} ${destroot}${prefix}/bin
            reinplace "s,@PREFIX@,${prefix},g" ${destroot}${prefix}/bin/${exe}
            reinplace "s,@VER@,${version}\.0,g" ${destroot}${prefix}/bin/${exe}
        }
    }
}

variant cxx17 conflicts cxx20 description "Use C++17" {
    require_active_variants abseil cxx17
}

variant cxx20 conflicts cxx17 description "Use C++20" {
    require_active_variants abseil cxx20
    compiler.cxx_standard   2020
}

if ![variant_isset cxx17] {
    default_variants +cxx20
}

# pthread variant exists for testing purposes.
variant pthread conflicts tls description "Enforce pthread usage instead of TLS" {
    configure.cppflags-append   -DABSL_FORCE_THREAD_IDENTITY_MODE=ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
}

variant tls conflicts pthread description "Enforce TLS" {
    configure.cppflags-append   -DABSL_FORCE_THREAD_IDENTITY_MODE=ABSL_THREAD_IDENTITY_MODE_USE_TLS
}

if ![variant_isset pthread] {
    default_variants-append +tls
}

variant tests description "Build with tests enabled" {
    pre-configure {
        port_test_ver_check ${subport} ${version} ${revision}
    }

    configure.args-replace \
                -Dprotobuf_BUILD_TESTS:BOOL=OFF \
                -Dprotobuf_BUILD_TESTS:BOOL=ON

    test.run    yes
    test.target check
}
