# $Id: Portfile 80831 2011-07-18 20:47:54Z jmr@macports.org $

PortSystem          1.0
PortGroup           muniversal 1.0

categories          math
license             BSD
name                atlas
version             3.9.37
#revision            4

# additional versions
set lapackversion   3.3.0
set lapackname      lapack
set atlasdist       ${name}${version}.tar.bz2
set lapackdist      ${lapackname}-${lapackversion}.tgz

maintainers         jameskyle
platforms           darwin

description         Portable optimal linear algebra software
long_description    The current version provides a complete BLAS and LAPACK API.\
                    For many operations, ATLAS achieves performance on par with\
                    machine-specific tuned libraries.

homepage            http://math-atlas.sourceforge.net/

master_sites        sourceforge:math-atlas:atlas \
                    http://www.netlib.org/lapack:lapack

distfiles           ${atlasdist}:atlas \
                    ${lapackdist}:lapack

patchfiles          patch-SpewMakeInc.c.diff \
					patch-emit_mm_c.diff \
					patch-archinfo_freebsd_c.diff

checksums           atlas${version}.tar.bz2 \
                    sha1    71dd254dad1fc9ad3dec123a561706c9a1a5d7d1 \
                    rmd160  87bb689e7a956df74ea4091552ac3cfd30430093 \
                	lapack-${lapackversion}.tgz \
                    md5     84213fca70936cc5f1b59a7b1bf71697 \
                    sha1    4f0b103da52110e7f60d1d7676727103aca9785e \
                	rmd160  cc72e7c93ab13464fd892d684b00b910cbbd3b3e


use_parallel_build  no
build.target        build
build.dir           ${workpath}/${name}-${version}/build

variant gcc45 conflicts gcc42 gcc43 gcc44 description {build using macports-gcc-4.5} {}
variant gcc44 conflicts gcc42 gcc43 description {build using macports-gcc-4.4} {}
variant gcc43 conflicts gcc42 gcc44 conflicts universal description {build using macports-gcc-4.3} {}
variant gcc42 conflicts gcc43 gcc44 conflicts universal description {build using macports-gcc-4.2} {}

if { [variant_isset gcc42] } {
  set gccversion    4.2
} elseif { [variant_isset gcc43] } {
  set gccversion    4.3
} elseif { [variant_isset gcc45 ] } {
  set gccversion    4.5
} else {
  default_variants +gcc44
  set gccversion    4.4
}

set gccnumber       [join [split ${gccversion} .] ""]

destroot.dir        ${build.dir}
destroot.destdir    DESTDIR=${destroot}${prefix}
depends_lib         port:gcc${gccnumber} \
                    port:bzip2 \
                    port:gzip

if {[info exists depends_skip_archcheck]} {
    depends_skip_archcheck gcc${gccnumber}
}

configure.compiler  macports-gcc-${gccversion}

if { ${os.arch}=="i386" } {
    set universal_archs_supported { i386 x86_64 }
} else {
    set universal_archs_supported { ppc  ppc64 }
}

if {${build_arch} == "x86_64" || ${build_arch} == "ppc64" } {
  set my_arch 64
} else {
  set my_arch 32
}

configure.args      -C xc ${configure.cc} \
                    -C gc ${configure.cc} \
                    -C if ${configure.f77} \
                    -C ic ${configure.cc} \
                    -C dm ${configure.cc} \
                    -C sm ${configure.cc} \
                    -C dk ${configure.cc} \
                    -C sk ${configure.cc} \
                    --cc=${configure.cc} \
                    --with-netlib-lapack-tarfile=${distpath}/${lapackdist} \
                    -O 12 \
                    -b ${my_arch} \
                    -Fa alg -fPIC
                    
# At this point, no threading for ppc/ppc64

if {${build_arch} == "ppc" || ${build_arch} == "ppc64"} {
	configure.args-append	-t 0
}

# MacPorts defaults to ppc on G4 and G5, so we must override 64-bit detection
# by Atlas, even if we are on a G5

if {${build_arch} == "ppc" && ! [variant_isset universal]} {
    configure.args-delete	--cc=${configure.cc} \
    						-Fa alg -fPIC

	configure.args-append	--cc='${configure.cc} -m32' \
							-A 4 \
    						-Fa alg '-fPIC -m32'
    
    # On Leopard, we may warn the user that ppc is not as efficient as ppc64
    if {${os.major} == 9} {
    	if {[exec sysctl -n hw.cpu64bit_capable] == 1} {
    		ui_msg	"--- Compiling for G4 arch (ppc) on a G5 (ppc64) machine."
    		ui_msg	"--- This will lead to inferior performance."
    	}
    }
}

if { [variant_isset universal] } {
    configure.universal_args-delete --disable-dependency-tracking
    configure.args-delete	--cc=${configure.cc} \
    						-b ${my_arch} \
    						-Fa alg -fPIC
                    
    lappend merger_configure_args(ppc)		--cc='${configure.cc} -m32' \
    										-b 32 \
    										-A 4 \
											-t 0 \
    										-s gas_ppc \
    										-Fa alg '-fPIC -m32'
    lappend merger_configure_args(ppc64)	--cc='${configure.cc} -m64' \
    										-b 64 \
    										-A 5 \
											-t 0 \
    										-s gas_ppc \
    										-Fa alg '-fPIC -m64'
    lappend merger_configure_args(i386) 	--cc='${configure.cc} -m32' \
    										-b 32 \
    										-s gas_x86_32 \
    										-Fa alg '-fPIC -m32'
    lappend merger_configure_args(x86_64) 	--cc='${configure.cc} -m64' \
    										-b 64 \
    										-s gas_x86_64 \
    										-Fa alg '-fPIC -m64'
} else {
    lappend merger_configure_args(ppc)
    lappend merger_configure_args(ppc64)
    lappend merger_configure_args(i386)
    lappend merger_configure_args(x86_64)
}

build.env-append    "CC=${configure.cc} CXX=${configure.cxx}"

# we are configuring from the build directory
configure.dir       ${workpath}/${name}-${version}/build
configure.cmd       ../configure


# change the default compilers to those of gcc and make into shared library
extract {
    # extract atlas and move to a consistent working directory name
    system "cd ${workpath} && bunzip2 -dc ${distpath}/${atlasdist} | \
         gnutar --no-same-owner -xf -"
    system "mv ${workpath}/ATLAS ${workpath}/${name}-${version}"
}

post-patch {
    	reinplace "s|__MACPORTS_GCC__|${configure.cc}|g" \
    		${workpath}/${name}-${version}/CONFIG/src/SpewMakeInc.c
}

# Bug in 3.9.37
proc bug3_9_37 {arch path} {
    switch ${arch} {
    	
    	x86_64 {
    		reinplace -E \
    			"s|ATL_thread_exit.o ATL_thread_join.o|\
    			ATL_thread_exit.o ATL_thread_join.o\
    			ATL_DecAtomicCount_amd64.o|" ${path}
    	}
    		
    	i386 {
    		reinplace -E \
    			"s|ATL_thread_exit.o ATL_thread_join.o|\
				ATL_thread_exit.o ATL_thread_join.o\
   				ATL_DecAtomicCount_ia32.o|" ${path}
    	}

    	ppc64 {
    		reinplace -E \
    			"s|ATL_thread_exit.o ATL_thread_join.o|\
    			ATL_thread_exit.o ATL_thread_join.o\
    			ATL_DecAtomicCount_ppc.o|" ${path}
    	}

    	ppc {
    		reinplace -E \
    			"s|ATL_thread_exit.o ATL_thread_join.o|\
    			ATL_thread_exit.o ATL_thread_join.o\
    			ATL_DecAtomicCount_ppc.o|" ${path}
    	}
	}
}

pre-configure {
    if { [variant_isset universal] } {
        foreach arch ${universal_archs_to_use} {
            copy ${workpath}/${name}-${version} ${workpath}/${name}-${version}-${arch}
        }
    }

    reinplace "s|cc=gcc|cc=${configure.cc}|g" ${worksrcpath}/configure
    reinplace "s|-no-cpp-precomp||g" ${workpath}/${name}-${version}/CONFIG/src/atlcomp.txt

    # Get some system specific variables for maximum optimization
    set cpufreq [expr {[exec sysctl -n hw.cpufrequency]/1000000}]
    ui_debug "Setting CPU Frequency for: ${cpufreq}"

    if {[string equal "${os.arch}" "powerpc"]} {
      configure.args-append -D c -DWALL
    } else {
      configure.args-append -D c -DPentiumCPS=${cpufreq}
    }

    if { [variant_isset universal] } {
        set archs ${universal_archs_to_use}
    } else {
        set archs ${build_arch}
    }

    foreach arch ${archs} {

    	if { ! [variant_isset universal] } {
        set atlas_path  ${workpath}/${name}-${version}
    	} else {
        set atlas_path ${workpath}/${name}-${version}-${arch}
    	}
    	
    	file mkdir ${atlas_path}/build
    	
    	# Correct a bug in 3.9.37
    	set mkt ${atlas_path}/makes/Make.thr
    	bug3_9_37 ${arch} ${mkt}
	}
}

post-configure {
    if { [variant_isset universal] } {
        set archs ${universal_archs_to_use}
    } else {
        set archs ${build_arch}
    }

    foreach arch ${archs} {
        if { ! [variant_isset universal] } {
            set atlas_path  ${workpath}/${name}-${version}
        } else {
            set atlas_path ${workpath}/${name}-${version}-${arch}
        }

    # recursively remove directories
    ui_debug "reinplace for make to recursively remove directories on clean"
    reinplace "s|rm -f|rm -rf|g" ${atlas_path}/build/Makefile
    }
}

proc make_dylib { lib lib_dir arch libs } {
    global destroot prefix gccnumber
    system "cd ${lib_dir} && \
            ( test ! -e ${lib}.a || \
              /usr/bin/ld -arch ${arch} -dynamic -dylib -single_module -dead_strip \
              -x -all_load -L. -L${prefix}/lib/gcc${gccnumber}/${arch} \ -L${prefix}/lib/gcc${gccnumber} -ldylib1.o \
              -dylib_install_name ${prefix}/lib/${lib}.dylib \
              ${lib}.a -o ${lib}.dylib ${libs} )"
}

post-build {
  # We have to manually create the dylib shared libs as the default build does not do this

  set ncpu [exec sysctl -n hw.ncpu]

    if { [variant_isset universal] } {
        set archs ${universal_archs_to_use}
    } else {
        set archs ${build_arch}
    }

    foreach arch ${archs} {
        if { ! [variant_isset universal] } {
            set atlas_path  ${workpath}/${name}-${version}
        } else {
            set atlas_path ${workpath}/${name}-${version}-${arch}
        }
        set lib_dir ${atlas_path}/build/lib

  make_dylib libatlas ${lib_dir} ${arch} { -lSystem }

  if {${ncpu} == "1" } {
    # there are no threaded libraries (libpt*) on single-core machines
    make_dylib libcblas   ${lib_dir} ${arch} { -latlas -lSystem }
    make_dylib libf77blas ${lib_dir} ${arch} { -lgfortran -latlas -lSystem }
  } else {
    make_dylib libptcblas   ${lib_dir} ${arch} { -latlas -lSystem }
    make_dylib libptf77blas ${lib_dir} ${arch} { -lgfortran -latlas -lSystem }
  }

  make_dylib liblapack ${lib_dir} ${arch} { -lf77blas -lcblas -latlas -lgfortran -lgcc_s.1 -lSystem }
}
}

pre-destroot {
   if { [variant_isset universal] } {
        set archs ${universal_archs_to_use}
    } else {
        set archs ${build_arch}
    }

    foreach arch ${archs} {
        if { ! [variant_isset universal] } {
            set atlas_path  ${workpath}/${name}-${version}
            set dest_path   ${destroot}${prefix}/lib/
        } else {
            set atlas_path ${workpath}/${name}-${version}-${arch}
            set dest_path  ${destroot}-${arch}${prefix}/lib/
        }
        set lib_dir ${atlas_path}/build/lib

        file mkdir ${dest_path}
        eval xinstall -m 755 [glob ${lib_dir}/*.dylib] ${dest_path}
    }
}

post-destroot {
    if { ![file exists ${destroot}${prefix}/lib/libcblas.dylib] && [file exists ${destroot}${prefix}/lib/libptcblas.dylib]} {
        ln -s libptcblas.dylib ${destroot}${prefix}/lib/libcblas.dylib
    }
    if { ![file exists ${destroot}${prefix}/lib/libf77blas.dylib] && [file exists ${destroot}${prefix}/lib/libptf77blas.dylib]} {
        ln -s libptf77blas.dylib ${destroot}${prefix}/lib/libf77blas.dylib
    }
}

livecheck.name      math-atlas
livecheck.distname  Stable
