# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
# $Id: Portfile 119638 2014-05-02 23:02:36Z sean@macports.org $

PortSystem          1.0
PortGroup           compiler_blacklist_versions 1.0
PortGroup           select 1.0

name                openmpi
version             1.7.5
revision            1
set branch          [join [lrange [split ${version} .] 0 1] .]
categories          science parallel net
platforms           darwin
license             BSD
maintainers         sean openmaintainer
description         A High Performance Message Passing Library
long_description    Open MPI is a project combining technologies and resources \
            from several other projects (FT-MPI, LA-MPI, LAM/MPI, and \
            PACX-MPI) in order to build the best MPI library available. A \
            completely new MPI-2 compliant implementation, Open MPI offers \
            advantages for system and software vendors, application developers \
            and computer science researchers.

# 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

homepage            http://www.open-mpi.org/
set subdir          ompi/v${branch}/downloads/
master_sites        http://www.open-mpi.org/software/${subdir} \
                    http://www.open-mpi.de/software/${subdir} \
                    http://icl.cs.utk.edu/open-mpi/${subdir}
# keep md5 & sha1 checksums as they are published on http://www.open-mpi.org/software/ompi/v1.7/
checksums           md5     321ab81147ac69a5bbca72652fb3b468 \
                    sha1    4a0de91c50a51e588810cc03d48c03429f3c1006 \
                    rmd160  ee410ead12a4c26afb76aaeef87304b78ce4ad8a \
                    sha256  cb3eef6880537d341d5d098511d390ec853716a6ec94007c03a0d1491b2ac8f2
use_bzip2           yes

livecheck.type      regex
livecheck.url       http://www.open-mpi.org/software/ompi/v1.7/
livecheck.regex     openmpi-(\[0-9\.\]+).tar.bz2

if {[string first "-devel" $subport] > 0} {
    version             1.9a1
    revision            31596
    name                openmpi-devel
    distname            openmpi-${version}r${revision}

    master_sites        http://www.open-mpi.org/nightly/trunk \
                        http://www.open-mpi.de/nightly/trunk

    checksums           md5     301eb14ab1666b5b343e9986ed77d247 \
                        sha1    af9c2b2cc513f6236e4a0ee0256699b44f79a2af \
                        rmd160  a33cbad3642a910ad1b5e1282df951ec299216c9 \
                        sha256  d22eeaae95ee5dc1e827b94fbdd7b47b08db1cb37d4e1f8efa8b1f5c77f5778c

    livecheck.version   ${revision}
    livecheck.url       http://www.open-mpi.org/nightly/trunk
    livecheck.regex     openmpi-${version}r(\[0-9\]+).tar.bz2
}

# As OpenMPI 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 {}

pre-extract { file mkdir ${workpath}/build }

# https://trac.macports.org/ticket/39089
compiler.blacklist  gcc-4.0
compiler.blacklist-append  llvm-gcc-4.2 macports-llvm-gcc-4.2

configure.dir       ${workpath}/build
configure.cmd       ${worksrcpath}/configure
configure.args      --enable-mpi-fortran \
                    "FFLAGS='' F77=''" \
                    --with-wrapper-ldflags="-Wl,-flat_namespace" \
                    LIBS="-Wl,-flat_namespace"

# remove -arch from ldflags, ticket #22833
configure.ld_archflags
configure.ccache no

# 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

build.dir           ${configure.dir}
destroot.dir        ${build.dir}

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:hwloc
    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   \
        --bindir=${prefix}/libexec/${name}-${cname} \
        --libdir=${prefix}/lib/${name}-${cname} \
        --sysconfdir=${prefix}/etc/${name}-${cname} \
        --includedir=${prefix}/include/${name}-${cname} \
        --datadir=${prefix}/share/${name}-${cname} \
        --docdir=${prefix}/share/docdelete \
        --mandir=${prefix}/share/mandelete \
        --with-hwloc=${prefix}

    post-destroot {
        if {[string first "-devel" $subport] > 0} {
            # Supply our own -devel manpages (might be materially different / new)
            file mkdir ${destroot}${prefix}/share/doc
            move ${destroot}${prefix}/share/mandelete \
                ${destroot}${prefix}/share/docdelete/man
            move ${destroot}${prefix}/share/docdelete \
                ${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 manpages
            if {[file isdirectory ${destroot}${prefix}/share/mandelete]} {
                delete ${destroot}${prefix}/share/mandelete
            }
            if {[file isdirectory ${destroot}${prefix}/share/docdelete]} {
                delete ${destroot}${prefix}/share/docdelete
            }
        }

        set vampirlog ${destroot}${prefix}/share/${name}-${cname}/vampirtrace/config.log
        if { [ file exists $vampirlog ] } {
            delete $vampirlog
        }

        foreach bin {mpirun mpiexec mpicc mpicxx mpif77 mpif90} {
            system -W ${destroot}${prefix}/share/$name-$cname/openmpi \
                "ln -sf $bin-wrapper-data.txt $bin-$name-$cname-wrapper-data.txt"
            system -W ${destroot}${prefix}/bin \
                "ln -sf ${prefix}/libexec/$name-$cname/$bin $bin-$name-$cname"
        }
    }

    if { [string first gcc $cname] == 0 } {
        configure.args-delete   --disable-mpi-fortran
        configure.args-append   --enable-mpi-fortran
        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-mpi-fortran
        configure.args-append   --enable-mpi-fortran
        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-mpi-fortran
                configure.args-append   --enable-mpi-fortran
                select.file             ${filespath}/${name}-${cname}-fortran

                configure.fc  ${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-mpi-fortran
            configure.args-append   --enable-mpi-fortran
            select.file             ${filespath}/${name}-${cname}-fortran

            configure.fc ${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 "

+--- OpenMPI 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 threads description {enable threads for MPI applications} {
        configure.args-append --enable-opal-multi-threads --enable-orte-progress-threads --enable-mpi-thread-multiple
    }

    variant valgrind description {enable valgrind support} {
        depends_lib-append    path:${prefix}/lib/pkgconfig/valgrind.pc:valgrind
        configure.args-append --enable-debug --enable-memchecker --with-valgrind=${prefix}
    }

} 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"
    }
}
