# -*- 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           muniversal 1.1
PortGroup           compilers 1.0
PortGroup           xcode_workaround 1.0
PortGroup           makefile 1.0

name                OpenBLAS
categories          math science
license             BSD
maintainers         {nicos @NicosPavlov} {michaelld @michaelld} {@catap korins.ky:kirill} openmaintainer
description         OpenBLAS is an optimized BLAS library based on GotoBLAS2
long_description    {*}${description}

# Block compilers that do not support thread-local storage.
compiler.cxx_standard 2011
compiler.c_standard   2011
compiler.thread_local_storage yes

if {${os.major} < 9} {
    # For older versions, we force native variant as there is no PPCG3 target in OpenBLAS
    default_variants-append +native
}

subport OpenBLAS-devel {}
if {[string first "-devel" $subport] > 0} {

    github.setup    OpenMathLib OpenBLAS 48b1b7cbc917bffa6f320b11783578ca6b525f38
    github.tarball_from archive
    version         20230921-[string range ${github.version} 0 7]
    checksums       rmd160  5910b6fdc4cb67f8e32f12fab303156aca5b330b \
                    sha256  4fededf4eecb0def7d27217d098f44ba7029618fb46539b39e528de3a75c420b \
                    size    24303945
    revision        0

    conflicts       OpenBLAS

    patchfiles      patch-libnoarch.devel.diff \
                    patch-destroot-layout.diff \
                    patch-OpenBLAS-i386-Apple.diff

    github.livecheck.branch develop

    # Not using precompiled binaries in -devel support
    default_variants-append +native

} else {

    github.setup    OpenMathLib OpenBLAS 0.3.25 v
    github.tarball_from releases
    checksums       rmd160  eea6fe2c33762df4c47c7241808dabbdb085eed3 \
                    sha256  4c25cb30c4bb23eddca05d7d0a85997b8db6144f5464ba7f8c09ce91e2f35543 \
                    size    24073168
    revision        0

    conflicts       OpenBLAS-devel

    patchfiles      patch-libnoarch.release.diff \
                    patch-destroot-layout.diff \
                    patch-OpenBLAS-i386-Apple.diff

    if {![variant_isset native]} {
        notes "
        This version is built based on a base architecture for convenience,
        which may not be optimized for your system. To build a version
        customized for your machine, use the +native variant"
    }
}

compilers.choose    fc

compilers.setup     default_fortran

variant lapack description "Add Lapack/CLapack support to the library" { }
default_variants-append +lapack

variant native description "Force compilation on machine to get fully optimized library" {
    # Prevent precompiled binaries to let compilation optimise the library for the user processor
    archive_sites
}

use_configure       no

# Workaround for test failure :-
# > ./sblat2 < ./sblat2.dat
# Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
xcode_workaround.fixed_xcode_version 11.2
xcode_workaround.type append_to_compiler_name

pre-build {
    set makeINC [open ${build.dir}/Makefile.rule "w"]
    puts $makeINC "VERSION = 1"
    puts $makeINC "LIBNAMESUFFIX = "

    puts $makeINC "CC = ${configure.cc}"
    puts $makeINC "FC = ${configure.fc}"

    if {${muniversal.build_arch} in [list arm64 ppc64 x86_64]} {
        puts $makeINC "BINARY = 64"
    } else {
        puts $makeINC "BINARY = 32"
    }

    puts $makeINC "COMMON_OPT = -O3"
    puts $makeINC "COMMON_PROF = -pg"

    if {![variant_isset lapack]} {
        puts $makeINC "NO_LAPACK = 1"
    }

    if {![variant_isset native]} {
        # Do not limit threads to the number on buildbots
        puts $makeINC "NUM_THREADS = 56"

        switch ${muniversal.build_arch} {
            arm64 {
                puts $makeINC "TARGET = ARMV8"
            }
            x86_64 {
                if {${os.major} >= 18} {
                    puts $makeINC "TARGET = NEHALEM"
                } else {
                    puts $makeINC "TARGET = CORE2"
                }
            }
            i386 {
                puts $makeINC "TARGET = YONAH"
            }
            ppc {
                puts $makeINC "TARGET = PPCG4"
            }
            ppc64 {
                puts $makeINC "TARGET = PPC970"
            }
            default {

            }
        }
    }

    # This fixes Rosetta build: https://trac.macports.org/ticket/64986
    if {${os.platform} eq "darwin" && ${os.major} == 10 && ${muniversal.build_arch} eq "ppc"} {
        puts $makeINC "HOSTARCH = PPCG4"
    }

    if {${muniversal.build_arch} ni [list i386 x86_64]} {
        # not on x86 of some sort; just disable AVX
        puts $makeINC "NO_AVX = 1"
        puts $makeINC "NO_AVX2 = 1"
        puts $makeINC "NO_AVX512 = 1"
    } else {
        if {![avx_compiler_isset]} {
            puts $makeINC "NO_AVX = 1"
        }
        # Disable AVX2 on OSX10.6 and older only.
        # On newer platforms AVX2 is now supported via
        # https://github.com/macports/macports-ports/pull/3486
        if { ${os.major} <= 10 } {
            puts $makeINC "NO_AVX2 = 1"
        }
        # Deactivating AVX512 instructions which do not build
        # at this point. Keeping them in -devel subport. See
        # https://trac.macports.org/ticket/57912
        if {[string first "-devel" $subport] < 1} {
            puts $makeINC "NO_AVX512 = 1"
        }
    }
    # Add configurations to build (not configurable yet as per original Makefile.rule)
    puts $makeINC "BUILD_SINGLE = 1"
    puts $makeINC "BUILD_DOUBLE = 1"
    puts $makeINC "BUILD_COMPLEX = 1"
    puts $makeINC "BUILD_COMPLEX16 = 1"
    close $makeINC
}

build.args          "AR=${prefix}/bin/ar RANLIB=${prefix}/bin/ranlib"
depends_build-append        path:libexec/coreutils/libstdbuf.so:coreutils \
                            port:cctools
depends_skip_archcheck      coreutils \
                            cctools

platform darwin 8 {
    depends_build-append    port:gmake
    build.cmd               ${prefix}/bin/gmake

    depends_test-append     port:gmake
    test.cmd                build.cmd
}

muniversal.combine          ${prefix}/lib/pkgconfig/openblas.pc

# Avoid conflict with Atlas
build.args-append           OPENBLAS_INCLUDE_DIR=${prefix}/include/openblas
destroot.args-append        OPENBLAS_INCLUDE_DIR=${prefix}/include/openblas

post-destroot {
    # For compatibility, put header files in ${prefix}/include
    foreach h [glob -tails -directory "${destroot}${prefix}/include/openblas" *.h] {
        if {${h} eq "cblas.h"} {
            ln -s openblas/${h} ${destroot}${prefix}/include/cblas_openblas.h
        } else {
            ln -s openblas/${h} ${destroot}${prefix}/include/${h}
        }
    }

    if {${muniversal.build_arch} ne ${configure.build_arch}} {
        reinplace "s|^openblas_config=|#openblas_config=|" ${destroot}${prefix}/lib/pkgconfig/openblas.pc
    }

    # Correct library name
    system "install_name_tool -id \
        ${prefix}/lib/libopenblas-r1.dylib \
        ${destroot}${prefix}/lib/libopenblas-r1.dylib"

    delete file ${destroot}${prefix}/lib/cmake
}
