1#!/bin/bash 2 3# This script builds Octave / Matlab interfaces for macOS. 4# A Matlab installation must be specified in order to build the 5# Matlab interface. The paths should not contain spaces! 6# 7# The script is known to work on macOS 10.5 Catalina with Homebrew. 8# 9# At least the following packages are required: 10# octave gnu-sed cunit 11# 12# 13# Example call: 14# ./macos-build-mex.sh --matlab=/path/to/matlab 15# 16 17# Any subsequent commands which fail will cause the shell script to exit immediately 18set -ex 19 20GCCARCH=haswell 21FFTWDIR=/usr/local 22GCC="gcc-9 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" 23 24# default values (to be overwritten if respective parameters are set) 25OCTAVEDIR=/usr/local 26 27# read the options 28TEMP=`getopt -o o:m:f:v: --long octave:,matlab:,matlab-version:,fftw: -n 'macos-build-mex.sh' -- "$@"` 29eval set -- "$TEMP" 30 31# extract options and their arguments into variables. 32while true ; do 33 case "$1" in 34 -o|--octave) 35 case "$2" in 36 "") shift 2 ;; 37 *) OCTAVEDIR=$2; shift 2 ;; 38 esac ;; 39 -m|--matlab) 40 case "$2" in 41 "") shift 2 ;; 42 *) MATLABDIR=$2; shift 2 ;; 43 esac ;; 44 -v|--matlab-version) 45 case "$2" in 46 "") shift 2 ;; 47 *) MATLABVERSION=$2; shift 2 ;; 48 esac ;; 49 --) shift ; break ;; 50 *) echo "Internal error!" ; exit 1 ;; 51 esac 52done 53 54NFFTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 55HOMEDIR="$NFFTDIR"/macos-build-mex 56mkdir -p "$HOMEDIR" 57cd "$HOMEDIR" 58GCCVERSION=`$GCC -dumpversion` 59FFTWVERSION=`fftw-wisdom | grep fftw- | gsed 's/(fftw-//' | gsed 's/ fftw_wisdom.*//'` 60OCTAVEVERSION=`"$OCTAVEDIR"/bin/octave-cli --eval "fprintf('OCTAVE_VERSION=%s\n', version); exit;" | grep OCTAVE_VERSION | gsed 's/OCTAVE_VERSION=//'` 61 62# Build NFFT 63READMECONTENT=" 64$(gsed -e '/^\[!/d' -e '/Directory structure/Q' $NFFTDIR/README) 65" 66FFTWREADME=' 67FFTW 68---- 69The compiled NFFT files contain parts of the FFTW library (http://www.fftw.org) 70Copyright (c) 2003, 2007-14 Matteo Frigo 71Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology' 72BINARIES_ARCH_README=' 73Please note that since the binaries were compiled with gcc flag -march=haswell, 74they may not work on older CPUs (below Intel i3/i5/i7-4xxx or 75AMD Excavator/4th gen Bulldozer) as well as on some Intel Atom/Pentium CPUs. 76' 77 78cd "$NFFTDIR" 79make distclean || true 80 81for OMPYN in 1 82do 83if [ $OMPYN = 1 ]; then 84 NFFTBUILDDIR="$HOMEDIR/build-openmp" 85 OMPFLAG="--enable-openmp" 86 OMPLIBS="-fopenmp -static-libgcc" 87 THREADSSUFFIX="_threads" 88 OMPSUFFIX="-openmp" 89 FFTW_LINK_COMMAND="-Wl,-force_load,$FFTWDIR/lib/libfftw3_threads.a -Wl,-force_load,$FFTWDIR/lib/libfftw3.a" 90else 91 NFFTBUILDDIR="$HOMEDIR/build" 92 OMPFLAG="" 93 OMPLIBS="-static-libgcc" 94 THREADSSUFFIX="" 95 OMPSUFFIX="" 96 FFTW_LINK_COMMAND="-Wl,-force_load,$FFTWDIR/lib/libfftw3.a" 97fi 98 99rm -f -r "$NFFTBUILDDIR" 100mkdir "$NFFTBUILDDIR" 101cd "$NFFTBUILDDIR" 102 103CC=$GCC CPPFLAGS=-I"$FFTWDIR"/include LDFLAGS=-L"$FFTWDIR"/lib "$NFFTDIR/configure" --enable-all $OMPFLAG --with-octave="$OCTAVEDIR" --with-gcc-arch=$GCCARCH --disable-static --enable-shared --disable-examples --enable-applications 104make 105make check 106 107NFFTVERSION=$( grep 'Version: ' nfft3.pc | cut -c10-) 108 109# Create archive for Julia interface 110cd julia 111for LIB in nf*t 112do 113 cd "$LIB" 114 $GCC -dynamiclib -o lib"$LIB"julia.dylib .libs/lib"$LIB"julia.o -Wl,-force_load,../../.libs/libnfft3_julia.a $FFTW_LINK_COMMAND -lm -O3 -malign-double -march=$GCCARCH $OMPLIBS 115 cd .. 116done 117 118cd fastsum 119$GCC -dynamiclib -o libfastsumjulia.dylib .libs/libfastsumjulia.o -Wl,-force_load,../../.libs/libnfft3_julia.a $FFTW_LINK_COMMAND -Wl,-force_load,../../applications/fastsum/.libs/libfastsum$THREADSSUFFIX.a -Wl,-force_load,../../applications/fastsum/.libs/libkernels.a -lm -O3 -malign-double -march=$GCCARCH $OMPLIBS 120cd .. 121 122cd "$NFFTBUILDDIR" 123 124ARCH=$(uname -m) 125JULIADIR=nfft-"$NFFTVERSION"-julia-macos_$ARCH$OMPSUFFIX 126mkdir "$JULIADIR" 127rsync -rLt --exclude='Makefile*' --exclude='doxygen*' --exclude='*.c.in' --exclude='*.c' --exclude='*.h' "$NFFTDIR/julia/" "$JULIADIR" 128rsync -rLt --exclude='Makefile*' --exclude='.deps' --exclude='.libs' --exclude='*.la' --exclude='*.lo' --exclude='*.o' --exclude='*.c' 'julia/' "$JULIADIR" 129 130for DIR in $JULIADIR/nf*t $JULIADIR/fastsum; do cd $DIR; for NAME in simple_test*.jl; do julia "$NAME"; done; cd "$NFFTBUILDDIR"; done; 131 132echo 'This archive contains the NFFT' $NFFTVERSION 'Julia interface. 133The NFFT library was compiled with double precision support for '$ARCH' macOS 134using GCC '$GCCVERSION' with -march='$GCCARCH' and FFTW '$FFTWVERSION'. 135'"$BINARIES_ARCH_README""$READMECONTENT""$FFTWREADME" > "$JULIADIR"/readme-julia.txt 136zip -9 -r ../"$JULIADIR".zip "$JULIADIR" 137# End of Julia interface 138 139 140# Create Matlab/Octave release 141for LIB in nfft nfsft nfsoft nnfft fastsum nfct nfst fpt 142do 143 cd matlab/"$LIB" 144 $GCC -o .libs/lib"$LIB".mex -bundle .libs/lib"$LIB"_la-"$LIB"mex.o -Wl,-force_load,../../.libs/libnfft3_matlab.a -Wl,-force_load,../../matlab/.libs/libmatlab.a -L"$OCTAVEDIR"/lib/octave/"$OCTAVEVERSION" $FFTW_LINK_COMMAND -lm -loctinterp -loctave -O3 -malign-double -march=$GCCARCH $OMPLIBS 145 cd ../.. 146done 147 148DIR=nfft-$NFFTVERSION-mexmaci64$OMPSUFFIX 149mkdir $DIR 150rsync -rLt --exclude='Makefile*' --exclude='doxygen*' --exclude='*.c.in' --exclude='*.c' --exclude='*.h' "$NFFTDIR/matlab/" "$DIR" 151rsync -rLt --exclude='Makefile*' --exclude='.deps' --exclude='.libs' --exclude='*.la' --exclude='*.lo' --exclude='*.o' --exclude='*.c' "matlab/" "$DIR" 152 153# Compile with Matlab 154if [ -n "$MATLABDIR" ]; then 155 if [ -z "$MATLABVERSION" ]; then 156 MATLABVERSION=`"$MATLABDIR"/bin/matlab -wait -nodesktop -nosplash -r "fprintf('MATLAB_VERSION=%s\n', version); exit;" | grep MATLAB_VERSION | gsed 's/.*(//' | gsed 's/)//'` 157 fi 158 MATLABSTRING="and Matlab $MATLABVERSION " 159 cd "$NFFTBUILDDIR" 160 make clean 161 CC=$GCC CPPFLAGS=-I"$FFTWDIR"/include LDFLAGS=-L"$FFTWDIR"/lib "$NFFTDIR/configure" --enable-all $OMPFLAG --with-matlab="$MATLABDIR" --with-gcc-arch=$GCCARCH --disable-static --enable-shared --disable-examples --disable-applications 162 make 163 make check 164 for LIB in nfft nfsft nfsoft nnfft fastsum nfct nfst fpt 165 do 166 cd matlab/"$LIB" 167 $GCC -o .libs/lib"$LIB".mexmaci64 -bundle .libs/lib"$LIB"_la-"$LIB"mex.o -Wl,-force_load,../../.libs/libnfft3_matlab.a -Wl,-force_load,../../matlab/.libs/libmatlab.a -L"$MATLABDIR"/bin/maci64 -lm -lmwfftw3 -lmx -lmex -lmat -O3 -malign-double -march=$GCCARCH $OMPLIBS 168 cd ../.. 169 done 170fi 171 172for SUBDIR in nfft nfsft nfsoft nnfft fastsum nfct nfst fpt 173 do 174 cp -f -L matlab/$SUBDIR/*.mex* "$DIR"/$SUBDIR/ 175done 176 177for SUBDIR in nfft nfsft nfsoft nnfft fastsum nfct nfst infft1d fpt ; do 178 cd "$DIR/$SUBDIR" 179 if [ -f simple_test.m ] ; then 180 for TESTFILE in *test*.m 181 do 182 if [ "$SUBDIR" != "infft1d" ] ; then 183 "$OCTAVEDIR"/bin/octave-cli --eval="run('$TESTFILE')" 184 fi 185 if [ -n "$MATLABDIR" ]; then 186 "$MATLABDIR"/bin/matlab -wait -nodesktop -nosplash -r "run('$TESTFILE'); exit" 187 fi 188 done 189 fi 190 cd "$NFFTBUILDDIR" 191done 192 193cd "$NFFTBUILDDIR" 194cp "$NFFTDIR"/COPYING "$DIR"/COPYING 195if [ -n "$MATLABDIR" ]; then 196echo 'This archive contains the Matlab and Octave interface of NFFT '$NFFTVERSION' 197compiled for '$ARCH' macOS using GCC '$GCCVERSION' with -march='$GCCARCH' 198'$MATLABSTRING'and Octave '$OCTAVEVERSION'. 199'"$BINARIES_ARCH_README""$READMECONTENT""$FFTWREADME" > "$DIR"/readme-matlab.txt 200else 201echo 'This archive contains the Octave interface of NFFT '$NFFTVERSION' 202compiled for '$ARCH' macOS using GCC '$GCCVERSION' with -march='$GCCARCH' 203and Octave '$OCTAVEVERSION'. 204'"$BINARIES_ARCH_README""$READMECONTENT""$FFTWREADME" > "$DIR"/readme-matlab.txt 205fi 206 207zip -9 -r ../"$DIR".zip "$DIR" 208 209done 210