#!/bin/bash
#
# Build script for op25 on Fedora and Ubuntu
#
#
#
# Updates: wget http://www.sbrac.org/files/build-gnuradio && chmod a+x ./build-gnuradio && ./build-gnuradio
# Updates: https://github.com/balint256/gr-baz.git
#
#
function help {
	cat <<!EOF!
	
Usage: build-gnuradio [--help|-h] [-v|--verbose] [-jN] [-ja] 
                      [-l|--logfile logfile ] [-u|--users ulist] funcs

-v|--verbose   - turn on verbose logging to stdout

-jN            - have make use N concurrent jobs

-ja            - have make use N concurrent jobs with auto setting of N
                 (based on number of cpu cores on build system)
                 
                
-l|--logfile lf - log messages to 'lf'
-svntag <tag>       - set tag for op25 checkout to <tag>
-e|--extras     - add an item to "extras" to be built after OP25
available funcs are:

all             - do all functions
prereqs         - install prerequisites
svnfetch        - use SVN to fetch OP25
op25_build  	- build op25 blocks, imbe_vocoder, and repeater
blocks_build	- build op25 blocks
blocks_build	- build op25 imbe_vocoder
repeater_build	- build op25 repeater

!EOF!

}

if [ $USER = root -o $UID -eq 0 ]
then
	echo Please run this script as an ordinary user
	echo   it will acquire root privileges as it needs them via \"sudo\".
	exit
fi

VERBOSE=No
JFLAG=""
LOGDEV=/dev/null
ANDYMODE=FALSE
SVNTAG=None
export LC_LANG=C
EXTRAS=""

while : 
do
	case $1 in
		-ja)
			cnt=`grep 'processor.*:' /proc/cpuinfo|wc -l`
			cnt=`expr $cnt - 1`
			if [ $cnt -lt 1 ]
			then
				cnt=1
			fi
			JFLAG=-j$cnt
			shift
			;;
			
		-j[123456789])
			JFLAG=$1
			shift
			;;

		-andy)
			ANDYMODE=True
			shift
			;;
			
		-v|--verbose)
			LOGDEV=/dev/stdout
			shift
			;;
			
		-l|--logfile)
			case $2 in
				/*)
					LOGDEV=$2
				;;
				*)
					LOGDEV=`pwd`/$2
				;;
			esac
			shift
			shift
			rm -f $LOGDEV
			echo $LOGDEV Starts at: `date` >>$LOGDEV 2>&1
			;;
			
		
		-h|--help)
			help
			exit
			;;
			
		-svnt)
			SVNTAG=$2
			shift
			shift
			;;
			
			
		-*)
			echo Unrecognized option: $1
			echo
			help
			exit
			break
			;;
		*)
			break
			;;
	esac
done

CWD=`pwd`
SUDOASKED=n
SYSTYPE=unknown
good_to_go=no
for files in /etc/fedora-release /etc/lsb-release /etc/debian_version /etc/redhat-release
do
	if [ -f $file ]
	then
		good_to_go=yes
	fi
done
if [ $good_to_go = no ]
then
	echo Supported systems are: Fedora, Ubuntu, Redhat, Debian
	echo You appear to be running none of the above, exiting
	exit
fi

echo This script will install OP25 from current SVN sources
echo You will require Internet access from the computer on which this
echo script runs.  You will also require SUDO access.  You will require
echo approximately 100MB of free disk space to perform the build.
echo " "
echo The whole process may take up to two hours to complete, depending on the
echo capabilities of your system.
echo
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo NOTE: if you run into problems while running this script, you can re-run it with
echo the --verbose option to produce lots of diagnostic output to help debug problems.
echo This script has been written to anticipate some of the more common problems one might
echo encounter building ANY large, complex software package.  But it is not pefect, and
echo there are certainly some situations it could encounter that it cannot deal with
echo gracefully.  Altering the system configuration from something reasonably standard,
echo removing parts of the filesystem, moving system libraries around arbitrarily, etc,
echo it likely cannot cope with.  It is just a script.  It isn\'t intuitive or artificially
echo intelligent.  It tries to make life a little easier for you, but at the end of the day
echo if it runs into trouble, a certain amount of knowledge on your part about
echo system configuration and idiosyncrasies will inevitably be necessary.
echo
echo
echo -n Proceed?

read ans
case $ans in
	y|yes|Y|YES|Yes)
		PROCEED=y
	;;
	*)
		exit
esac

SPACE=`df $HOME| grep -v blocks|grep '%'`
SPACE=`echo $SPACE | awk '/./ {n=NF-2; printf ("%d\n", $n/1.0e3)}'`


if [ $SPACE -lt 100 ]
then
	echo "You don't appear to have enough free disk space on $HOME"
	echo to complete this build/install
	echo exiting
	exit
fi

total=0
for file in op25.20* 
do
	if [ -d $file ]
	then
		sz=`du -s $file|awk '{print $1}'`
		total=`expr $total + $sz`
	fi
done
total=`expr $total '*' 1024`
total=`expr $total / 1000000`
if [ $total -gt 50 ]
then
	echo Your old 'op25.*' directories are using roughly $total MB
	echo of disk space:
	ls -ld op25.20* 
	echo " "
	echo -n Remove them'?'
	read ans
	
	case $ans in
		yes|YES)
			echo removing op25.20* 
			rm -rf op25.20*
			echo Done
			;;
	esac
fi
rm -rf *.20*.bgmoved

function my_echo {
	if [ $LOGDEV = /dev/stdout ]
	then
		echo $*
	else
		echo $*
		echo $* >>$LOGDEV 2>&1
	fi
}

function checkcmd {
	found=0
	for place in /bin /usr/bin /usr/local/bin
	do
		if [ -e $place/$1 ]
		then
			found=1
		fi
	done
	if [ $found -eq 0 ]
	then
		my_echo Failed to find just-installed command \'$1\' after pre-requisite installation.
		my_echo This very likely indicates that the pre-requisite installation failed
		my_echo to install one or more critical pre-requisites for Gnu Radio/UHD
		exit
	fi
}

function checklib {
	found=0
	my_echo -n Checking for library $1 ...
	for dir in /lib /usr/lib /usr/lib64 /lib64 /usr/lib/x86_64-linux-gnu /usr/lib/i386-linux-gnu
	do
		for file in $dir/${1}*.so*
		do
			if [ -e "$file" ]
			then
				found=1
			fi
		done
	done
	if [ $found -le 0 ]
	then
		my_echo Failed to find libraries with prefix \'$1\' after pre-requisite installation.
		my_echo This very likely indicates that the pre-requisite installation failed
		my_echo to install one or more critical pre-requisites for Gnu Radio/UHD
		my_echo exiting build
		exit
	else
		my_echo Found library $1
	fi
}

function checkpkg {
	my_echo Checking for package $1
	if [ `apt-cache search $1 | wc -l` -eq 0 ]
	then
		my_echo Failed to find package \'$1\' in known package repositories
		my_echo Perhaps you need to add the Ubuntu universe or multiverse PPA?
		my_echo see https://help.ubuntu.com/community/Repositories/Ubuntu
		my_echo exiting build
		exit
	fi
}
		
function prereqs {
	sudocheck
	my_echo -n Installing prequisites...
	#
	# It's a Fedora system
	#
	if [ -f /etc/fedora-release ]
	then
		my_echo Fedora has not been tested with this script please report results to the op25-dev yahoo group
		SYSTYPE=Fedora
		case `cat /etc/fedora-release` in
		*12*|*13*|*14*|*15*|*16*|*17*)
			sudo yum -y groupinstall "Engineering and Scientific" "Development Tools" >>$LOGDEV 2>&1
			sudo yum -y install swig g++ automake libtool python-dev libfftw3-dev \
			  libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries \
			  libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev \
			  libqt4-dev python-numpy ccache python-opengl libgsl0-dev \
			  python-cheetah python-lxml doxygen qt4-dev-tools \
			  libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools libitpp-dev \
			  bison flex libgtk2.0-dev libpcap-dev subversion >>$LOGDEV 2>&1
		;;
		*)
			my_echo Only Fedora release 12 - 17 are supported by this script
			exit
			;;
		esac
	
	#
	# It's a RedHat system
	elif [ -f /etc/redhat-release ]
	then
		my_echo Readhat has not been tested with this script please report results to the op25-dev yahoo group
		SYSTYPE=Redhat
		case `cat /etc/redhat-release` in
		*elease*6*)
			sudo yum -y groupinstall "Engineering and Scientific" "Development Tools" >>$LOGDEV 2>&1
			sudo yum -y install swig g++ automake libtool python-dev libfftw3-dev \
			  libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries \
			  libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev \
			  libqt4-dev python-numpy ccache python-opengl libgsl0-dev \
			  python-cheetah python-lxml doxygen qt4-dev-tools \
			  libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools libitpp-dev \
			  bison flex libgtk2.0-dev libpcap-dev subversion  >>$LOGDEV 2>&1
		;;
		*)
			my_echo Your Redhat system release must be release 6 to proceed
			exit
			;;
		esac
	#
	# It's a Ubuntu system
	#
	elif [ -f /etc/lsb-release ]
	then
		SYSTYPE=Ubuntu
		case `grep DISTRIB_RELEASE /etc/lsb-release` in
		*11.*|*12.*|*13*)
			PKGLIST="swig g++ automake libtool python-dev libfftw3-dev 
			libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries 
			libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev 
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev 
			python-cheetah python-lxml doxygen qt4-dev-tools 
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools libitpp-dev 
			bison flex libgtk2.0-dev libpcap-dev subversion"
			;;
			
		*10.04*|*10.10*)
			my_echo Your Ubuntu is untested please report results to the op25-dev yahoo email group
			PKGLIST="swig g++ automake libtool python-dev libfftw3-dev 
			libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries 
			libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev 
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev 
			python-cheetah python-lxml doxygen qt4-dev-tools 
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools libitpp-dev 
			bison flex libgtk2.0-dev libpcap-dev subversion"
			;;
			
		*9.10*)
			my_echo Your Ubuntu is untested please report results to the op25-dev yahoo email group
			PKGLIST="swig g++ automake libtool python-dev libfftw3-dev 
			libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries 
			libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev 
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev 
			python-cheetah python-lxml doxygen qt4-dev-tools 
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools libitpp-dev 
			bison flex libgtk2.0-dev libpcap-dev subversion"
			;;
			
		*9.04*)
			my_echo Your Ubuntu is untested please report results to the op25-dev yahoo email group
			PKGLIST="swig g++ automake libtool python-dev libfftw3-dev 
			libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries 
			libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev 
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev 
			python-cheetah python-lxml doxygen qt4-dev-tools 
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools libitpp-dev 
			bison flex libgtk2.0-dev libpcap-dev subversion"
			;;
			
		*)
			my_echo Your Ubuntu release must be at least 9.04 to proceed
			exit
			;;
		esac
		for pkg in $PKGLIST; do checkpkg $pkg; done
		sudo apt-get -y --ignore-missing install $PKGLIST >>$LOGDEV 2>&1
	#
	# It's a Debian system
	#
	elif [ -f /etc/debian_version ]
	then
		SYSTYPE=Debian
		my_echo Debian is untested please report results to the op25-dev yahoo email group
		case `cat /etc/debian_version` in
		*6.0*|*wheezy*|*sid*)
			PKGLIST="swig g++ automake libtool python-dev libfftw3-dev 
			libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries 
			libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev 
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev 
			python-cheetah python-lxml doxygen qt4-dev-tools 
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools libitpp-dev 
			bison flex libgtk2.0-dev libpcap-dev subversion"
			;;
		*)
			my_echo Only Debian release 6 is supported
			exit
			;;
		esac
		for pkg in $PKGLIST; do checkpkg $pkg; done
		sudo apt-get -y --ignore-missing install $PKGLIST >>$LOGDEV 2>&1
	elif [ -f /etc/SuSE-release ]
	then
		SYSTYPE=OpenSuSE
		if grep -q 12.1 /etc/SuSE-release
		then
			cool=1
		else
			my_echo Only OpenSuSE 12.1 is supported by this script
			exit
		fi
		sudo zypper install cmake cppunit-devel doxygen fftw3-devel \
		git gsl-devel libjack-devel libqt4-devel libqwtplot3d-devel \
		libSDL-devel libusb-1_0-devel orc portaudio portaudio-devel \
		python-cheetah python-devel python-lxml python-wxGTK python-wxWidgets-devel \
		qwt-devel wxWidgets-devel xmlto texlive-latex subversion >>$LOGDEV 2>&1
		
	else
		my_echo This script supports only Ubuntu,Fedora and Debian systems
		my_echo Your Fedora system must be at least Fedora 12
		my_echo Your Ubuntu system must be at least Ubuntu 9.04
		my_echo Your Debian system must be release 6
		exit
	fi
	PATH=$PATH
	export PATH

	checkcmd guile
	checkcmd git
	checkcmd cmake
	
	if [ $SYSTYPE = Fedora ]
	then
		checklib libusb-0 0
		checklib libusb-1 0
	else
		checklib libusb 2
	fi
	
	checklib libboost 5
	checklib libcppunit 0
	checklib libguile 5
	checklib libfftw 5
	checklib libgsl 0
	
	my_echo Done
}


function svnfetch {
	date=`date +%Y%m%d%H%M%S`

	#
	# Check for existing op25 directory
	#
	
	if [ -d op25 ]
	then
		mv op25 op25.$date
	fi

	
	#
	# SVN the gnu radio source tree
	#
	my_echo -n Fetching OP25 via SVN...
	if [ $SVNTAG != None ]
	then
		svn co $SVNTAG http://op25.osmocom.org/svn/trunk op25 >>$LOGDEV 2>&1
	else
		svn co http://op25.osmocom.org/svn/trunk op25 >>$LOGDEV 2>&1
	
	fi
	my_echo Done
	
}

function op25_build {
	#
	# op25 build
	#
	sudocheck
	if [ ! -d op25 ]
	then
		my_echo you do not appear to have the \'op25\' directory
		my_echo you should probably use $0 svnfetch to fetch the appropriate
		my_echo files using svn
		exit
	fi
	my_echo -n Building OP25...
	blocks_build
	imbe_build
	repeater_build
	my_echo Done building/installing OP25
}


function blocks_build {
	#
	# blocks build
	#
	sudocheck
	if [ ! -d op25 ]
	then
		my_echo you do not appear to have the \'op25\' directory
		my_echo you should probably use $0 svnfetch to fetch the appropriate
		my_echo files using svn
		exit
	fi
	cd op25
	if [ ! -d blocks ]
	then
		my_echo you do not appear to have the \'op25\/blocks\' directory
		my_echo you should probably use $0 svnfetch to fetch the appropriate
		my_echo files using svn
		exit
	fi
	my_echo -n Building op25\/blocks\/...
	cd blocks
	./bootstrap >>$LOGDEV 2>&1
	./configure >>$LOGDEV 2>&1
	make clean >/dev/null 2>&1
	make >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo OP25 Make apparently failed
		my_echo Exiting blocks build
		exit
	fi
	sudo make check >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo OP25 Make Check apparently failed
		my_echo Exiting blocks build
		exit
	fi
	sudo make install >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo OP25 Make Install apparently failed
		my_echo Exiting blocks build
		exit
	fi
	
	sudo ldconfig >>$LOGDEV 2>&1
	my_echo Done building/installing blocks
}

function imbe_build {
	#
	# op25/imbe_vocoder build
	#
	sudocheck
	if [ ! -d op25 ]
	then
		my_echo you do not appear to have the \'op25\' directory
		my_echo you should probably use $0 svnfetch to fetch the appropriate
		my_echo files using svn
		exit
	fi
	cd op25
	if [ ! -d imbe_vocoder ]
	then
		my_echo you do not appear to have the \'op25\/imbe_vocoder\' directory
		my_echo you should probably use $0 svnfetch to fetch the appropriate
		my_echo files using svn
		exit
	fi
	my_echo -n Building op25\/imbe_vocoder\/...
	cd imbe_vocoder
	./bootstrap >>$LOGDEV 2>&1
	./configure >>$LOGDEV 2>&1
	make clean >/dev/null 2>&1
	make >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo imbe_vocoder Make apparently failed
		my_echo Exiting imbe_vocoder build
		exit
	fi
	sudo make check >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo imbe_vocoder Make Check apparently failed
		my_echo Exiting imbe_vocoder build
		exit
	fi
	sudo make install >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo imbe_vocoder Make Install apparently failed
		my_echo Exiting OP25 build
		exit
	fi
	
	sudo ldconfig >>$LOGDEV 2>&1
	my_echo Done building/installing imbe_vocoder
}


function repeater_build {
	#
	# op25/repeater build
	#
	sudocheck
	if [ ! -d op25 ]
	then
		my_echo you do not appear to have the \'op25\' directory
		my_echo you should probably use $0 svnfetch to fetch the appropriate
		my_echo files using svn
		exit
	fi
	cd op25
	if [ ! -d repeater ]
	then
		my_echo you do not appear to have the \'op25\/repeater\' directory
		my_echo you should probably use $0 svnfetch to fetch the appropriate
		my_echo files using svn
		exit
	fi
	my_echo -n Building op25\/repeater...
	cd repeater
	./bootstrap >>$LOGDEV 2>&1
	./configure >>$LOGDEV 2>&1
	make clean >/dev/null 2>&1
	make >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo op25\/repeater Make apparently failed
		my_echo Exiting repeater build
		exit
	fi
	sudo make check >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo repeater Make Check apparently failed
		my_echo Exiting repeater build
		exit
	fi
	sudo make install >>$LOGDEV 2>&1
	if [ $? -ne 0  ]
	then
		my_echo repeater Make Install apparently failed
		my_echo Exiting repeater build
		exit
	fi
	
	sudo ldconfig >>$LOGDEV 2>&1
	my_echo Done building/installing repeater
}

function all {
	my_echo Starting all functions at: `date`
	cd $CWD
	prereqs
	touch -d "15 minutes ago" touch$$
	if [ -d op25 -a ]
	then
		if [ op25 -ot touch$$ ]
		then
			svnfetch
		else
			my_echo Skipping svn fetch, since \'op25\' is new enough
		fi
	else
		svnfetch
	fi
	rm -f touch$$
	for fcn in blocks_build imbe_build repeater_build pythonpath
	do
		my_echo Starting function $fcn at: `date`
		cd $CWD
		$fcn
		my_echo Done function $fcn at: `date`
	done
	my_echo Done all functions at: `date`
}

function pythonpath {
	for PYVER in 2.6 2.7
	do
		for type in "" 64
		do
			if [ -d /usr/local/lib${type}/python${PYVER}/site-packages/gnuradio ]
			then
				PYTHONPATH=/usr/local/lib${type}/python${PYVER}/site-packages
			fi
			if [ -d /usr/local/lib${type}/python${PYVER}/dist-packages/gnuradio ]
			then
				PYTHONPATH=/usr/local/lib${type}/python${PYVER}/dist-packages
			fi
		done
	done
	echo
	echo
	echo "************************************************************"
	echo You should probably set your PYTHONPATH to:
	echo " "
	echo "    " $PYTHONPATH
	echo " "
	echo Using:
	echo " "
	echo export PYTHONPATH=$PYTHONPATH
	echo " "
	echo in your .bashrc or equivalent file prior to attempting to run
	echo any Gnu Radio applications or Gnu Radio Companion.
	echo "*************************************************************"
}

function sudocheck {
	#
	# Check SUDO privileges
	#
	if [ $SUDOASKED = n ]
	then
		echo SUDO privileges are required 
		echo -n Do you have SUDO privileges'?'
		read ans
		case $ans in
			y|yes|YES|Y)
				echo Continuing with script
				SUDOASKED=y
				sudo grep timestamp_timeout /etc/sudoers >tmp$$
				timeout=`cat tmp$$|awk '/./ {print $4}'`
				rm -f tmp$$
				if [ "@@" = "@$timeout@" ]
				then
					sudo cp /etc/sudoers tmp$$
					sudo chown $USER tmp$$
					sudo chmod 644 tmp$$
					echo "Defaults  timestamp_timeout = 90" >>tmp$$
					sudo cp tmp$$ /etc/sudoers
					sudo chown root /etc/sudoers
					sudo chmod 440 /etc/sudoers
				elif [ $timeout -lt 90 ]
				then
					echo You need to have a timestamp_timout in /etc/sudoers of 90 or more
					echo Please ensure that your timestamp_timeout is 90 or more
					exit
				fi
				;;
			*)
				echo Exiting.  Please ensure that you have SUDO privileges on this system!
				exit
				;;
		esac
	fi
}

PATH=$PATH
export PATH
case $# in
	0)
		all
		my_echo All Done
		exit
esac

for arg in $*
do
	cd $CWD
	$arg
done
my_echo All Done

