#!/bin/bash
#
# build-c30.sh
# version 0.3   (see bottom of file for change history)
#
# (C) 2010 Matt Jervis <dev@electricrock.co.nz>
# http://www.electricrock.co.nz/blog
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# This build script is not in any way associated with Microchip 
# Technology Inc. and is not supported by them. If you need help
# then contact the author(s) of the script, contact details above.
# 
#
#         Instructions
#         ------------
#
# Use this script to build Microchip's GCC based C30 compiler.  
# Tested with v3.23b on Ubuntu 10.04.
#
# The -f flag on the command line will cause it to overwrite without
# asking first and cause checkinstall to run with defaults.
#
# Prerequisites:  build-essential bison flex tofrodos wine checkinstall
# sudo aptitude install build-essential bison flex tofrodos wine checkinstall
# to install on Ubuntu.
#
# This script does not clean up temporary directories created
# as part of the build process.
#
# Please read through the script before running!
#

#
##########################################################################
#
# Modify the following environment variables to set the location
# of the sources, and build destination, etc.  

# Comment the following lines to disable execution of that stage
ENABLE_BINUTILS=n
ENABLE_GCC=n
ENABLE_NONFREE=y

# Comment to disable installation (compile only)
ENABLE_INSTALL=y

# Temporary directory in which to build the compiler
C30BUILD=/tmp/c30/build

# Prefix to install the compiler
C30INSTALL=/usr/local

# The wineprefix is where the non-free part will be temporarily  installed.
WINEPREFIX=/tmp/c30/non-free

# C30 Version (changing it here updates the SRC_PATH variables below)
C30VER=3_23b

# Patch Version
PATCHVER=v01

# Path to the binutils sources (typically mplabalc30v3_xx.tar.gz)
BINUTILS_SRC_PATH=$HOME/Downloads/mplabalc30v$C30VER.tar.gz

# Path to gcc sources (typically mplabc30v3_xx.tar.gz)
GCC_SRC_PATH=$HOME/Downloads/mplabc30v$C30VER.tar.gz

# Path to the non-free installer executable
NONFREE_INSTALLER_PATH=$HOME/Downloads/MPLABC30Combo_v${C30VER}_LITE.exe

# Path to binutils patches
BINUTILS_PATCHES_PATH=$HOME/Downloads/pic30-binutils-$PATCHVER.tar.bz2

# Path to GCC patches
GCC_PATCHES_PATH=$HOME/Downloads/pic30-gcc-$PATCHVER.tar.bz2

# Comment this line out if super user privileges are not required for install
SUDO_CMD=sudo

#
##########################################################################
#
#  No changes /should/ need to be made after this point
#

BINUTILS_DIR=$C30BUILD/binutils
GCC_DIR=$C30BUILD/gcc

if [ "$1" = "-f" ]; then
    FORCE=y
    CHECKINSTALL_AUTO_ACCEPT="--default"
fi


#
# check if the build dir already exists
#
if [ -d $C30BUILD ] && [ ! "$FORCE" = "y" ]; then
    read -p "C30 build dir $C30BUILD already exists, continue (y/N)? " REPLY
    if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then
	exit 1
    fi
fi


#
#-----------------          binutils          ----------------- 
#

function build_binutils {
# 1. Create directory and unzip the sources and patches

    mkdir -p $BINUTILS_DIR
    if [ ! -d $BINUTILS_DIR ]; then
	echo "$0  -  Unable to create directory $BINUTILS_DIR."
	exit 1
    fi

    cd $BINUTILS_DIR

    echo "$0  -  Unzipping binutils sources"
    tar -zxvf $BINUTILS_SRC_PATH > /dev/null
    if [ $? != 0 ]; then
	echo "Unable to unzip $BINUTILS_SRC_PATH"
	exit 2
    fi

    echo "$0  -  Unzipping binutils patches"
    tar -jxvf $BINUTILS_PATCHES_PATH > /dev/null
    if [ $? != 0 ]; then
	echo "Unable to unzip $BINUTILS_PATCHES_PATH"
	exit 2
    fi

# 2. Convert files to unix line endings
    echo "$0  -  Converting to unix line endings"
    find . -type f -exec fromdos '{}' ';'

# 3. Apply patches
    echo "$0  -  Applying patches"
    for patchfile in pic30-binutils-$PATCHVER/patches/*.diff; do 
	patch -p0 < $patchfile > /dev/null
	if [ $? != 0 ] && [ ! "$FORCE" = "y" ]; then
	    read -p "Error applying patch: $patchfile, continue (y/N)?" REPLY
	    if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then
		exit 1
	    fi
	fi
    done

# 4. Configure/make
    echo "$0  -  Configure, make"

    VER_DOTTED=`echo $C30VER | sed s/'_'/'.'/`
    FULL_VER="v$VER_DOTTED-Debian"

    cd acme
    CFLAGS=-DMCHP_VERSION=$FULL_VER ./configure \
	--prefix=$C30INSTALL --target=pic30-coff
    if [ $? != 0 ]; then
	echo "Error running configure"
	exit 2
    fi

# This is to fix linker script errors
    find . -name "*.y" -o -name "*.l" -exec touch '{}' ';'

    make
    if [ $? != 0 ]; then
	echo "Error running make"
	exit 2
    fi


# 5. Generate and install package
    if [ "$ENABLE_INSTALL" = "y" ]; then
	echo "$0  -  Generate and install package"
    
	mkdir doc-pak
	cp README COPYING doc-pak


	echo "Microchip C30 - binutils

This is the binutils part of Microchip's C Compiler for PIC24 MCUs and dsPIC 
DSCs (C30), based on GCC.
" > description-pak
	
    # Replace this line with make install if checkinstall does not 
    # support your distro.
	sudo checkinstall --pkgname="mplabalc30" \
	    --pkgversion=$VER_DOTTED $CHECKINSTALL_AUTO_ACCEPT

    fi
}


function build_gcc {
# 1. Create directory and unzip the sources and patches

    mkdir -p $GCC_DIR
    if [ ! -d $GCC_DIR ]; then
	echo "Unable to create directory $GCC_DIR."
	exit 1
    fi

    cd $GCC_DIR

    echo "$0  -  Unzipping gcc sources"
    tar -zxvf $GCC_SRC_PATH > /dev/null
    if [ $? != 0 ]; then
	echo "Unable to unzip $GCC_SRC_PATH"
	exit 2
    fi

    echo "$0  -  Unzipping gcc patches"
    tar -jxvf $GCC_PATCHES_PATH > /dev/null
    if [ $? != 0 ]; then
	echo "Unable to unzip $GCC_PATCHES_PATH"
	exit 2
    fi

# 2. Convert files to unix line endings
    echo "$0  -  Converting to unix line endings"
    find . -type f -exec fromdos '{}' ';'


# 3. Apply patches

    echo "$0  -  Applying patches"
    for patchfile in pic30-gcc-$PATCHVER/patches/*.diff; do 
	patch -p0 < $patchfile > /dev/null
	if [ $? != 0 ] && [ ! "$FORCE" = "y" ]; then
	    read -p "Error applying patch: $patchfile, continue (y/N)?" REPLY
	    if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then
		exit 1
	    fi
	fi
    done



# 4. Configure/make
    echo "$0  -  Configure, make"

    VER_DOTTED=`echo $C30VER | sed s/'_'/'.'/`
    FULL_VER="v$VER_DOTTED-Debian"

    mkdir build
    cd build

    CFLAGS=-DMCHP_VERSION=$FULL_VER ../gcc-4.0.2/gcc-4.0.2/configure \
	--prefix=$C30INSTALL --target=pic30-coff --enable-languages=c
    if [ $? != 0 ]; then
	echo "Error running configure"
	exit 2
    fi

    find . -name "*.y" -o -name "*.l" -exec touch '{}' ';'

    make
    if [ $? != 0 ]; then
	echo "Error running make"
	exit 2
    fi

# 5. Generate and install package
    if [ "$ENABLE_INSTALL" = "y" ]; then
	echo "$0  -  Generate and install package"

	mkdir doc-pak
	cp README COPYING doc-pak
	
	echo "Microchip C30 - gcc

This is the compiler part of Microchip's C Compiler for PIC24 MCUs and dsPIC 
DSCs (C30), based on GCC.
" > description-pak

	echo "#!/bin/bash
ln -s $C30INSTALL/bin/pic30-coff-as \
	$C30INSTALL/libexec/gcc/pic30-coff/4.0.3/pic30-coff-as
ln -s $C30INSTALL/bin/pic30-coff-ld \
	$C30INSTALL/libexec/gcc/pic30-coff/4.0.3/pic30-coff-ld
ln -s $C30INSTALL/bin/pic30-coff-gcc-4.0.3 \
	$C30INSTALL/bin/pic30-coff-gcc
" > postinstall-pak

	echo "#!/bin/bash
rm $C30INSTALL/libexec/gcc/pic30-coff/4.0.3/pic30-coff-as
rm $C30INSTALL/libexec/gcc/pic30-coff/4.0.3/pic30-coff-ld
rm $C30INSTALL/bin/pic30-coff-gcc
" > preremove-pak


    # Replace this line with make install if checkinstall does not 
    # support your distro.
	sudo checkinstall --pkgname="mplabc30" --pkgversion=$VER_DOTTED $CHECKINSTALL_AUTO_ACCEPT
    fi
}



function install_non_free {
    mkdir -p $WINEPREFIX
    export WINEPREFIX
    wineprefixcreate

    echo "Generating unattended install file."

    if [ $C30VER == "3_23" ]
    then
	echo "[InstallShield Silent]
Version=v7.00
File=Response File
[File Transfer]
OverwrittenReadOnly=NoToAll
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-DlgOrder]
Dlg0={387E64A5-42FA-4B67-A037-E63255F0FD47}-SdWelcome-0
Count=10
Dlg1={387E64A5-42FA-4B67-A037-E63255F0FD47}-SdLicense2Rtf-0
Dlg2={387E64A5-42FA-4B67-A037-E63255F0FD47}-SprintfBox-0
Dlg3={387E64A5-42FA-4B67-A037-E63255F0FD47}-SetupType2-0
Dlg4={387E64A5-42FA-4B67-A037-E63255F0FD47}-SdAskDestPath-0
Dlg5={387E64A5-42FA-4B67-A037-E63255F0FD47}-SdComponentTree-0
Dlg6={387E64A5-42FA-4B67-A037-E63255F0FD47}-SprintfBox-1
Dlg7={387E64A5-42FA-4B67-A037-E63255F0FD47}-SprintfBox-2
Dlg8={387E64A5-42FA-4B67-A037-E63255F0FD47}-SdStartCopy-0
Dlg9={387E64A5-42FA-4B67-A037-E63255F0FD47}-SdFinish-0
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SdWelcome-0]
Result=1
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SdLicense2Rtf-0]
Result=1
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SprintfBox-0]
Result=6
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SetupType2-0]
Result=303
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SdAskDestPath-0]
szDir=C:\C30
Result=1
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SdComponentTree-0]
szDir=C:\C30
Compiler\License-type=string
Compiler\License-count=1
Compiler\License-0=Compiler\License\LicenseC30
Compiler-type=string
Compiler-count=4
Compiler-0=Compiler\License
Compiler-1=Compiler\GenericSupport
Compiler-2=Compiler\PIC24support
Compiler-3=Compiler\dsPICsupport
PeriphLibSrc-type=string
PeriphLibSrc-count=3
PeriphLibSrc-0=PeriphLibSrc\PIC24LibSrc
PeriphLibSrc-1=PeriphLibSrc\dsPICLibSrc
PeriphLibSrc-2=PeriphLibSrc\CommonLibSrc
Component-type=string
Component-count=2
Component-0=Compiler
Component-1=PeriphLibSrc
Result=1
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SprintfBox-1]
Result=7
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SprintfBox-2]
Result=6
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SdStartCopy-0]
Result=1
[Application]
Name=MPLAB C for dsPIC DSCs and PIC24 MCUs - Lite
Version=3.23
Company=Microchip Technology Inc.
Lang=0009
[{387E64A5-42FA-4B67-A037-E63255F0FD47}-SdFinish-0]
Result=1
bOpt1=0
bOpt2=0
" > $WINEPREFIX/drive_c/setup.iss
    elif [ $C30VER == "3_23b" ]
    then
	echo "[InstallShield Silent]
Version=v7.00
File=Response File
[File Transfer]
OverwrittenReadOnly=NoToAll
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-DlgOrder]
Dlg0={1EE84E96-8AFE-4D54-9534-319804A546A4}-SdWelcome-0
Count=11
Dlg1={1EE84E96-8AFE-4D54-9534-319804A546A4}-SdLicense2Rtf-0
Dlg2={1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-0
Dlg3={1EE84E96-8AFE-4D54-9534-319804A546A4}-SetupType2-0
Dlg4={1EE84E96-8AFE-4D54-9534-319804A546A4}-SdAskDestPath-0
Dlg5={1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-1
Dlg6={1EE84E96-8AFE-4D54-9534-319804A546A4}-SdComponentTree-0
Dlg7={1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-2
Dlg8={1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-3
Dlg9={1EE84E96-8AFE-4D54-9534-319804A546A4}-SdStartCopy-0
Dlg10={1EE84E96-8AFE-4D54-9534-319804A546A4}-SdFinish-0
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SdWelcome-0]
Result=1
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SdLicense2Rtf-0]
Result=1
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-0]
Result=6
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SetupType2-0]
Result=303
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SdAskDestPath-0]
szDir=C:\C30
Result=1
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-1]
Result=7
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SdComponentTree-0]
szDir=C:\C30
Compiler\License-type=string
Compiler\License-count=1
Compiler\License-0=Compiler\License\LicenseC30
Compiler-type=string
Compiler-count=4
Compiler-0=Compiler\License
Compiler-1=Compiler\GenericSupport
Compiler-2=Compiler\PIC24support
Compiler-3=Compiler\dsPICsupport
Examples-type=string
Examples-count=1
Examples-0=Examples\dsPICExamples
PeriphLibSrc-type=string
PeriphLibSrc-count=3
PeriphLibSrc-0=PeriphLibSrc\PIC24LibSrc
PeriphLibSrc-1=PeriphLibSrc\dsPICLibSrc
PeriphLibSrc-2=PeriphLibSrc\CommonLibSrc
Component-type=string
Component-count=5
Component-0=Compiler
Component-1=Examples
Component-2=Documents
Component-3=StdLibSrc
Component-4=PeriphLibSrc
Result=1
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-2]
Result=6
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SprintfBox-3]
Result=6
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SdStartCopy-0]
Result=1
[Application]
Name=MPLAB C for dsPIC DSCs and PIC24 MCUs - Lite
Version=3.23
Company=Microchip Technology Inc.
Lang=0009
[{1EE84E96-8AFE-4D54-9534-319804A546A4}-SdFinish-0]
Result=1
bOpt1=0
bOpt2=0
" > $WINEPREFIX/drive_c/setup.iss


    fi

    echo
    echo "Running unattended install of $NONFREE_INSTALLER_PATH"
    echo "  (this might seem to hang, but it just takes a little hwile.)"
    echo

    wine $NONFREE_INSTALLER_PATH -s -f1"C:/setup.iss" -f2"C:/setup.log"

    # check if directory was correctly created
    if [ ! -d $WINEPREFIX/drive_c/C30 ]; then
	echo 
	echo "C30 Install in $WINEPREFIX/drive_c/C30 failed."
	echo
	exit 1
    fi

    $SUDO_CMD mkdir -p $C30INSTALL/share/pic30-nonfree

    if [ ! -d $C30INSTALL/share/pic30-nonfree ]; then
	echo
	echo "Unable to create pic30-nonfree directory."
	exit 1
    fi

    $SUDO_CMD cp -r $WINEPREFIX/drive_c/C30/support \
	$C30INSTALL/share/pic30-nonfree
    $SUDO_CMD cp -r $WINEPREFIX/drive_c/C30/include \
	$C30INSTALL/share/pic30-nonfree
    $SUDO_CMD cp -r $WINEPREFIX/drive_c/C30/lib \
	$C30INSTALL/share/pic30-nonfree
    $SUDO_CMD cp $WINEPREFIX/drive_c/C30/bin/c30_device.info \
	$C30INSTALL/lib
    $SUDO_CMD ln -s $C30INSTALL/lib/c30_device.info \
	$C30INSTALL/bin
    $SUDO_CMD ln -s $C30INSTALL/lib/c30_device.info \
	$C30INSTALL/lib/gcc
    $SUDO_CMD ln -s $C30INSTALL/lib/c30_device.info \
	$C30INSTALL/libexec/gcc/pic30-coff/4.0.3    
}




if [ "$ENABLE_BINUTILS" = "y" ]; then
    build_binutils
fi
if [ "$ENABLE_GCC" = "y" ]; then
    build_gcc
fi
if [ "$ENABLE_NONFREE" = "y" ]; then
    install_non_free
fi

#
##########################################################################
#
#  CHANGELOG
#
#
# 	v 0.1		18/03/2010
# Initial version of script, tested on Ubuntu 9.10 with C30 v3.23
#
#	v 0.2		03/05/2010
# Changed dos2unix to fromdos as dos2unix as is no longer supported on
# Ubuntu 10.04. Tested on 10.04 with C30 v3.23
#
#	v 0.3		08/07/2010
# Updated unattended install script for v3.23b non-free.
# Tested on 10.04 with C30 v3.23b
#
