# -*- 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
# $Id: Portfile 119637 2014-05-02 23:02:33Z sean@macports.org $

PortSystem          1.0
PortGroup           compiler_blacklist_versions 1.0
PortGroup           select 1.0

name                mpich
version             3.1
revision            1

license             BSD
categories          science parallel net
platforms           darwin
maintainers         eborisch \
                    sean \
                    openmaintainer

description         Message Passing Interface (MPI) Library

long_description    MPICH is a high-performance and widely portable\
                    implementation of the Message Passing Interface (MPI) \
                    standard (MPI-1, MPI-2 and MPI-3). The goals of MPICH are:\
                    (1) to provide an MPI implementation that efficiently\
                    supports different computation and communication platforms\
                    including commodity clusters (desktop systems,\
                    shared-memory systems, multicore architectures), high-speed\
                    networks (10 Gigabit Ethernet, InfiniBand, Myrinet,\
                    Quadrics) and proprietary high-end computing systems (Blue\
                    Gene, Cray) and (2) to enable cutting-edge research in MPI\
                    through an easy-to-extend modular framework for other\
                    derived implementations.

homepage            http://www.mpich.org/
master_sites        ${homepage}static/tarballs/${version}/

# Since mpi is just a compiler wrapper, compiling it as universal needs to be
# supported upstream since it'd be a constantly moving target, for reference
# see, https://trac.macports.org/ticket/20240
universal_variant   no

checksums \
    rmd160  8d682dd615f38b927197c94d8255625be3a24a54 \
    sha256  fcf96dbddb504a64d33833dc455be3dda1e71c7b3df411dfcf9df066d7c32c39

livecheck.type      regex
livecheck.regex     mpich-(\[0-9.p\]+)${extract.suffix}
livecheck.url       ${homepage}downloads/index.php?s=downloads

if {[string first "-devel" $subport] > 0} {
    name                mpich-devel
    version             3.1
    revision            208
    # To see 3.1 as newer than 3.1rcX
    epoch               1
    distname            mpich-master-v${version}-${revision}-g62ada3c5

    master_sites        ${homepage}static/downloads/nightly/master/mpich

    checksums           rmd160  7a11c1cc5edc764da86851e5fcd33b8fa0fd1bd5 \
                        sha256  d4b06049dc446336769bb4219f1d6c1ad71fcabde169a6cef521cfd20d96cb5f

    livecheck.version   ${revision}
    livecheck.regex \
        mpich-master-v${version}-(\[0-9\]+)-\[0-9a-z\]+${extract.suffix}
    livecheck.url       ${master_sites}
}

# As MPICH creates compiler wrappers, there are lots of
# variants for what compiler the user would like to wrap.

# Sup-ports names and corresponding configure.compiler value
array set clist {
    clang   {clang}
    clang31 {macports-clang-3.1}
    clang32 {macports-clang-3.2}
    clang33 {macports-clang-3.3}
    clang34 {macports-clang-3.4}
    clang35 {macports-clang-3.5}
    gcc43   {macports-gcc-4.3}
    gcc44   {macports-gcc-4.4}
    gcc45   {macports-gcc-4.5}
    gcc46   {macports-gcc-4.6}
    gcc47   {macports-gcc-4.7}
    gcc48   {macports-gcc-4.8}
    gcc49   {macports-gcc-4.9}
    llvm    {llvm-gcc-4.2}
    dragonegg31 {macports-dragonegg-3.1}
    dragonegg32 {macports-dragonegg-3.2}
    dragonegg33 {macports-dragonegg-3.3}
}

foreach key [array name clist] {
    subport ${name}-${key} {}
    subport ${name}-devel-${key} {}
}
subport ${name}-default {}
subport ${name}-devel {}
subport ${name}-devel-default {}

# Linker for Apple clang version 421.11.66 segfaults
# See https://trac.macports.org/ticket/36654#comment:9
compiler.blacklist-append   {clang >= 421.11.66 < 425.0.24}

configure.args      --disable-dependency-tracking \
                    --disable-f77 \
                    --disable-fc \
                    --disable-silent-rules \
                    --enable-base-cache \
                    --enable-cache \
                    --enable-cxx \
                    --enable-fast=O2 \
                    --enable-shared \
                    --enable-smpcoll \
                    --with-device=ch3:nemesis \
                    --with-pm=hydra \
                    --with-thread-package=posix \
                    --enable-versioning \
                    "F90FLAGS='' F90=''"

platform darwin {
    configure.args-append   --enable-timer-type=mach_absolute_time
}

# We're making compiler wrappers here... don't default to -O2 for wrappers.
# Actual library code is compiled with -O2 via --enable-fast=O2 configure arg
configure.optflags-delete   -O2 -Os
configure.cppflags-delete   -I${prefix}/include
configure.ldflags-delete    -L${prefix}/lib

if {${subport} != ${name}} {
    set cname                   [lindex [split ${subport} -] end]
    if {${cname} == "default"} {
        set cname                   mp
    }

    if {[lsearch -exact {mp llvm clang} ${cname}] != -1} {
        # Force local builds with Xcode-provided compilers (avoid issues with
        # different Xcode versions on buildbot and user machines)
        archive_sites
    }

    conflicts-append            lammpi
    depends_lib-append          port:libxml2
    depends_run                 port:mpi_select port:mpi-doc
    select.group                mpi
    select.file                 ${filespath}/${name}-${cname}
    livecheck.type              none

    if {[string first "-default" $subport] < 0} {
        configure.compiler      [lindex $clist($cname) 0]
        append long_description "\\n\\nTHIS SUBPORT WRAPS ${cname}'s C/C++"
    } else {
        append long_description \
"\\n\\nTHIS SUBPORT WRAPS MACPORTS' DEFAULT COMPILER FOR C/C++"
    }

    configure.args-append   \
        --libdir=${prefix}/lib/${name}-${cname} \
        --sysconfdir=${prefix}/etc/${name}-${cname} \
        --program-suffix=-${name}-${cname} \
        --includedir=${prefix}/include/${name}-${cname}

    post-destroot {
        if {[string first "-devel" $subport] > 0} {
            # Supply our own -devel manpages (might be materially different /
            # new)
            move ${destroot}${prefix}/share/man \
                ${destroot}${prefix}/share/doc/mpich/
            move ${destroot}${prefix}/share/doc/mpich \
                ${destroot}${prefix}/share/doc/${name}-${cname}
            system -W ${destroot}${prefix}/share/doc/${name}-${cname}/man \
                "/usr/bin/find . -type f -print0 | /usr/bin/xargs -0 -P ${build.jobs} /usr/bin/gzip -v"
        } else {
            # This version doesn't supply doc/manpages
            if {[file isdirectory ${destroot}${prefix}/share/man]} {
                delete ${destroot}${prefix}/share/man
            }
            if {[file isdirectory ${destroot}${prefix}/share/doc]} {
                delete ${destroot}${prefix}/share/doc
            }
        }
    }

    if { [string first gcc $cname] == 0 } {
        configure.args-delete   --disable-f77 --disable-fc
        configure.args-append   --enable-f77 --enable-fc
        select.file             ${filespath}/${name}-${cname}-fortran
        variant fortran description {
            Stub : fortran always enabled for gcc-based version
        } {}
        default_variants-append     +fortran
    } elseif { [string first dragon $cname] == 0 } {
        configure.args-delete   --disable-f77 --disable-fc
        configure.args-append   --enable-f77 --enable-fc
        select.file             ${filespath}/${name}-${cname}-fortran
        variant fortran description {
            Stub : fortran always enabled for dragonegg-based version
        } {}
        default_variants-append     +fortran
    } else {
        set gcc_versions {4.3 4.4 4.5 4.6 4.7 4.8 4.9}
        set default_fortran_variant +gcc48
        set g95_conflicts {}

        foreach ver ${gcc_versions} {
            set ver_no_dot [join [split ${ver} "."] ""]

            set variant_line {variant gcc${ver_no_dot} description \
              "build with gfortran from gcc${ver_no_dot}" conflicts g95}

            foreach over ${gcc_versions} {
                if {${ver} == ${over}} {
                    continue
                }

                set over_no_dot [join [split ${over} "."] ""]
                append variant_line " conflicts gcc${over_no_dot}"
            }
            append variant_line { {}}

            eval $variant_line

            append g95_conflicts " conflicts gcc${ver_no_dot}"

            if {[variant_isset gcc${ver_no_dot}]} {
                if {${default_fortran_variant} != "+gcc${ver_no_dot}"} {
                    set default_fortran_variant ""
                }
            }
        }

        eval [concat {variant g95 description {build with g95}} \
              $g95_conflicts {{}}]

        if {[variant_isset g95]} {
            if {${default_fortran_variant} != "+g95"} {
                set default_fortran_variant ""
            }
        }

        if {${default_fortran_variant} != ""} {
            default_variants "${default_fortran_variant}"
        }

        foreach ver ${gcc_versions} {
            set ver_no_dot [join [split ${ver} "."] ""]

            if {[variant_isset gcc${ver_no_dot}]} {
                depends_lib-append path:lib/libgcc/libgcc_s.1.dylib:libgcc \
                                   port:gcc${ver_no_dot}

                configure.args-delete   --disable-f77 --disable-fc
                configure.args-append   --enable-f77 --enable-fc
                select.file             ${filespath}/${name}-${cname}-fortran

                configure.fc  ${prefix}/bin/gfortran-mp-${ver}
                configure.f77 ${prefix}/bin/gfortran-mp-${ver}
                configure.f90 ${prefix}/bin/gfortran-mp-${ver}
            }
        }

        if {[variant_isset g95]} {
            depends_lib-append path:lib/libgcc/libgcc_s.1.dylib:libgcc \
                               port:g95

            configure.args-delete   --disable-f77 --disable-fc
            configure.args-append \
                --enable-f77 --enable-fc lt_cv_ld_force_load=no
            select.file             ${filespath}/${name}-${cname}-fortran

            configure.fc ${prefix}/bin/g95
            configure.f77 ${prefix}/bin/g95
            configure.f90 ${prefix}/bin/g95
        }
    }

    set devnotes ""

    if {[string first "-devel" $subport] > 0} {
        set devnotes "
|
| To see the -devel MAN pages, add:
|   ${prefix}/share/doc/${name}-${cname}/man
| to the start of your MANPATH environment variable."
    }

notes "

+--- MPICH Usage note ----
| The mpicc wrapper (and friends) are installed as:
|
|   ${prefix}/bin/mpicc-${name}-${cname} (likewise mpicxx, ...)
|
| To make ${subport}'s wrappers the default (what you get when
| you execute 'mpicc' etc.) please run:
|
|   sudo port select --set mpi [file tail ${select.file}]${devnotes}
+-------------------------

"

    variant gforker description {
        Use gforker process manager instead of the default hydra
    } {
        configure.args-append   --with-pm=gforker
        configure.args-delete   --with-pm=hydra
    }

    variant tuned description {Build with more optimizations} {
        configure.args-delete   --enable-fast=O2
        configure.args-append   --enable-fast=all \
                                MPICHLIB_CFLAGS='-fomit-frame-pointer -O2'
    }
} else {
    depends_lib-append      port:$name-default
    distfiles
    supported_archs         noarch
    patch {}
    build {}
    configure {}
    destroot {
        set docdir          ${destroot}${prefix}/share/doc/${name}
        xinstall -d ${docdir}
        system "echo $name is a stub port > ${docdir}/README"
    }
}
