lazarus/tools/install/cross_unix/update_cross_fpc.sh
2007-10-16 20:32:10 +00:00

390 lines
12 KiB
Bash
Executable File

#!/usr/bin/env bash
# Author: Mattias Gaertner
# License: LGPL
# Abstract: Download, compile binutils and FPC
set -e
set -x
# This is the root for all download and building directories
if [ ! -d "$BuildRoot" ]; then
BuildRoot=~/freepascal
fi
# the binutils version to download
BinutilsVersion=2.18
BinutilsDownloadPath=http://ftp.gnu.org/gnu/binutils/
# the FPC targets
Targets="i386-win32";
# where to install the fpc+binutils executables
# Only used if called with 'install'. This directory must be in $PATH.
InstallBin=~/bin/
# what intel platform do you want/need to build for?
MyIntel=i686
#===============================================================================
# parse command line parameters
DownloadBinutils=no
DownloadFPC=no
BuildBinutils=no
BuildCrossFPC=no
BuildNormalFPC=no
CreateFPCCfg=no
InstallAsDefault=no # install ~/fpc.cfg, binaries to ~/bin
Params=$@
for p in $Params; do
case "$p" in
all)
DownloadBinutils=yes
DownloadFPC=yes
BuildBinutils=yes
BuildCrossFPC=yes
BuildNormalFPC=yes
CreateFPCCfg=yes
;;
downloadbinutils)
DownloadBinutils=yes
;;
downloadfpc)
DownloadFPC=yes
;;
buildbinutils)
BuildBinutils=yes
;;
buildnormalfpc)
BuildNormalFPC=yes
;;
buildcrossfpc)
BuildCrossFPC=yes
;;
createfpccfg)
CreateFPCCfg=yes
;;
install)
InstallAsDefault=yes
;;
installbin=*)
InstallBin=$(echo $p | sed -e 's#^installbin=##')
;;
buildroot=*)
BuildRoot=$(echo $p | sed -e 's#^buildroot=##')
;;
targets=*)
Targets=$(echo $p | sed -e 's#^targets=##')
;;
*)
echo "Unknown option: $p"
echo
echo "Usage:"
echo " $0 [all] [downloadbinutils] [downloadfpc] [buildbinutils] [buildnormalfpc] [buildcrossfpc] [createfpccfg] [install] [installbin=<dir>] [targets=<i386-win32>] [buildroot=<dir default=~/freepascal/>]"
exit -1
;;
esac
done
#===============================================================================
# expand paths
BuildRoot=$(echo $BuildRoot | sed -e 's#//#/#g' -e 's#/$##')
InstallBin=$(echo $InstallBin | sed -e 's#//#/#g' -e 's#/$##')
# the 'bin' directory - where to put the fpc+binutils executables
# On InstallAsDefault=yes they will be copied to $HomeBin
BinDir=$BuildRoot/bin/
CompilerName="ppc386"
# check install path
if [ $InstallAsDefault = "yes" ]; then
# check if the $InstallBin is in $PATH
TrimmedPath=$(echo $InstallBin | sed -e 's#/$##g' -e 's#//#/#')
if [ -z $(echo $PATH | egrep "(^|:)$TrimmedPath(:|$)") ]; then
echo "ERROR: $InstallBin not in \$PATH."
echo "This script installs FPC and binutils executables to a directory"
echo "that is in your search PATH before your installed FPC."
echo "Either prepend it to \$PATH or define another with installbin=<path>"
exit -1
fi
# check if $InstallBin is in PATH before the system compiler
mkdir -p $InstallBin
NewCompilerName=$InstallBin/$CompilerName
if [ ! -f $NewCompilerName ]; then
touch $NewCompilerName
chmod a+x $NewCompilerName
fi
hash -r
FoundFPC=$(which $CompilerName)
if [ ! $FoundFPC = $NewCompilerName ]; then
echo "ERROR: $InstallBin not early enough in \$PATH."
echo "This script installs FPC and binutils executables to a directory"
echo "that is in your search PATH before your installed FPC."
echo "Either prepend it to \$PATH or define another with installbin=<path>"
exit -1
fi
BinDir=$InstallBin
fi
#===============================================================================
# calculate targets
TARGETS_WIN="" # "cygwin mingw32 msdosdjgpp"
TARGETS_I386="" # "freebsd netbsd openbsd linux solaris darwin"
TARGETS_POWERPC="" # "freebsd netbsd openbsd linux darwin"
TARGETS_SPARC="" # "freebsd netbsd openbsd linux solaris"
TARGETS_M68k=
for Target in $Targets; do
if [ $Target = 'i386-win32' ]; then
TARGETS_WIN="$TARGETS_WIN mingw32"
else
TargetCPU=$(echo $Target | sed -e 's#^\(.*\)-.*$#\1#')
TargetOS=$(echo $Target | sed -e 's#^.*-\(.*\)$#\1#')
if [ $TargetCPU = 'i386' ]; then
TARGETS_I386="$TARGETS_I386 $TargetOS"
fi
if [ $TargetCPU = 'powerpc' ]; then
TARGETS_I386="$TARGETS_POWERPC $TargetOS"
fi
if [ $TargetCPU = 'sparc' ]; then
TARGETS_I386="$TARGETS_SPARC $TargetOS"
fi
if [ $TargetCPU = 'm86k' ]; then
TARGETS_I386="$TARGETS_M68k $TargetOS"
fi
fi
done
TARGETS_WIN=$(echo $TARGETS_WIN | sed -e 's#^ +##g' -e 's# +$##g')
TARGETS_I386=$(echo $TARGETS_I386 | sed -e 's#^ +##g' -e 's# +$##g')
TARGETS_POWERPC=$(echo $TARGETS_POWERPC | sed -e 's#^ +##g' -e 's# +$##g')
TARGETS_SPARC=$(echo $TARGETS_SPARC | sed -e 's#^ +##g' -e 's# +$##g')
TARGETS_M68k=$(echo $TARGETS_M68k | sed -e 's#^ +##g' -e 's# +$##g')
#===============================================================================
# Download binutils
DownloadDir=$BuildRoot/download
BinutilsFilename=binutils-$BinutilsVersion.tar.gz
BinutilsTGZ=$DownloadDir/$BinutilsFilename
if [ $DownloadBinutils = "yes" ]; then
if [ ! -f $BinutilsTGZ ]; then
mkdir -p $DownloadDir
cd $DownloadDir
echo "Downloading $BinutilsDownloadPath/$BinutilsFilename ..."
wget $BinutilsDownloadPath/$BinutilsFilename
fi
fi
#===============================================================================
# Download FPC - update existing or download stable tree
if [ $DownloadFPC = "yes" ]; then
cd $BuildRoot
if [ -d fpc ]; then
cd fpc
echo "SVN update for FPC ..."
svn cleanup
svn up
cd -
else
echo "SVN checkout for FPC 2.2 ..."
svn co http://svn.freepascal.org/svn/fpc/branches/fixes_2_2 fpc
fi
if [ -d install ]; then
cd install
echo "SVN update for FPC install ..."
svn cleanup
svn up
cd -
else
echo "SVN checkout for FPC 2.2 install ..."
svn co http://svn.freepascal.org/svn/fpcbuild/branches/fixes_2_2/install install
fi
fi
#===============================================================================
# setup some variables
# retrieve the version information
VersionFile="$BuildRoot/fpc/compiler/version.pas"
if [ ! -f $VersionFile ]; then
echo No FPC sources found. To download them call ./update_cross_fpc.sh DownloadFPC
exit
fi
CompilerVersion=`cat $VersionFile | grep ' *version_nr *=.*;' | sed -e 's/[^0-9]//g'`
CompilerRelease=`cat $VersionFile | grep ' *release_nr *=.*;' | sed -e 's/[^0-9]//g'`
CompilerPatch=`cat $VersionFile | grep ' *patch_nr *=.*;' | sed -e 's/[^0-9]//g'`
CompilerVersionStr="$CompilerVersion.$CompilerRelease.$CompilerPatch"
#===============================================================================
# build binutils
if [ $BuildBinutils = "yes" ]; then
# check if cc is there
cc -v
# check if bison is there
bison -V
# create custom version of buildcrossbinutils
echo "building cross binutils for targets:"
echo " WIN=$TARGETS_WIN"
echo " I386=$TARGETS_I386"
echo " POWERPC=$TARGETS_POWERPC"
echo " SPARC=$TARGETS_SPARC"
echo " M68K=$TARGETS_M68K"
cd $BuildRoot/install/cross/
cat buildcrossbinutils | \
sed -e 's#^BASE=.*$#BASE='"$BuildRoot"'/binutils#' \
-e 's#^BINUTILSPATH=.*$#BINUTILSPATH='"$DownloadDir"'/#' \
-e 's#^BINUTILSBASE=.*$#BINUTILSBASE=binutils#' \
-e 's#^BINUTILSVERSION=.*$#BINUTILSVERSION='"$BinutilsVersion"'#' \
-e 's#^BINUTILS_GZIP=.*$#BINUTILS_GZIP=yes#' \
-e 's#^\(TARGETS_.*=\).*$#\1#' \
-e 's#^TARGETS_WIN=.*$#TARGETS_WIN='"$TARGETS_WIN"'#' \
-e 's#^TARGETS_I386=.*$#TARGETS_I386='"$TARGETS_I386"'#' \
-e 's#^TARGETS_POWERPC=.*$#TARGETS_POWERPC='"$TARGETS_POWERPC"'#' \
-e 's#^TARGETS_SPARC=.*$#TARGETS_SPARC='"$TARGETS_SPARC"'#' \
-e 's#^TARGETS_M68k=.*$#TARGETS_M68k='"$TARGETS_M68k"'#' \
> buildcrossbinutils.sh
#debugging: head -n 50 buildcrossbinutils.sh
# build the cross binutils
echo "HINT: when something goes wrong see the log files in $BuildRoot/binutils/logs/"
rm -rf $BuildRoot/binutils
Command=$BuildRoot/install/cross/buildcrossbinutils.sh
echo "calling $Command ..."
Result=$(sh buildcrossbinutils.sh)
FailResult=$(echo "$Result" | grep -i failes || true)
if [ -n "$FailResult" ]; then
echo $Result
echo "HINT: see the log files in $BuildRoot/binutils/logs/"
exit -1
fi
# link binaries into the bin directory, so that FPC can find them
mkdir -p $BinDir
for Target in $Targets; do
TargetCPU=$(echo $Target | sed -e 's#^\(.*\)-.*$#\1#')
TargetOS=$(echo $Target | sed -e 's#^.*-\(.*\)$#\1#')
BinUtilsCPU=$TargetCPU
BinUtilsOS=$TargetOS
if [ $TargetOS = "win32" ]; then
BinUtilsOS="mingw32"
BinUtilsCPU=$MyIntel
fi
BinUtilsDir=$BuildRoot/binutils/cross/bin/
BinUtilsPrefix="$BinUtilsCPU-$BinUtilsOS-"
cd ${BinUtilsDir}
for binutility in $(ls -B ${BinUtilsPrefix}*); do
link=$(echo $binutility | sed -e "s#$BinUtilsPrefix#${TargetCPU}-${TargetOS}-#")
ln -sf ${BinUtilsDir}${binutility} ${BinDir}${link}
done
done
fi
#===============================================================================
# build cross FPC
if [ $BuildCrossFPC = "yes" ]; then
echo "building cross FPC ..."
for Target in $Targets; do
TargetCPU=$(echo $Target | sed -e 's#^\(.*\)-.*$#\1#')
TargetOS=$(echo $Target | sed -e 's#^.*-\(.*\)$#\1#')
# create custom version of buildcrosssnapshot
cd $BuildRoot/install/cross/
cat buildcrosssnaphot | \
sed -e 's#^CROSSTOOLSROOT=.*$#CROSSTOOLSROOT='"$BuildRoot"'/binutils/cross/#' \
-e 's#^FPCSVN=.*$#FPCSVN='"$BuildRoot"'/fpc#' \
-e 's#^FPCCVS=.*$#FPCCVS='"$BuildRoot"'/fpc#' \
-e 's#^TARGETS_OS=.*$#TARGETS_OS='"$TargetOS"'#' \
-e 's#^TARGETS_CPU=.*$#TARGETS_CPU='"$TargetCPU"'#' \
-e 's#^MOS=cygwin$#MOS=mingw32#' \
> buildcrosssnapshot.sh
#debugging: head -n 40 buildcrosssnapshot.sh
# build the cross fpc
echo "building cross fpc for target $Target in $BuildRoot/bintuils/cross/destination/"
echo "see logs in $BuildRoot/bintuils/cross/logs/"
sh buildcrosssnapshot.sh
done
fi
#===============================================================================
# build normal FPC
# compile the non cross FPC into the same structure, so that the fpc.cfg
# can be very simple.
if [ $BuildNormalFPC = "yes" ]; then
echo "building normal FPC ..."
CPU=i386 # `uname -p | tr "[:upper:]" "[:lower:]"`
OS=`uname -s | tr "[:upper:]" "[:lower:]"`
echo HOST platform is ${CPU}-${OS}
MAKE=make
case "$OS" in
*bsd*) MAKE=gmake
;;
esac
CROSSTOOLSROOT=$BuildRoot/binutils/cross/
DESTDIR=${CROSSTOOLSROOT}destination/
LOGDIR=${CROSSTOOLSROOT}logs/
BASELIBDIR=${CROSSTOOLSROOT}crosslibs
mkdir -p ${DESTDIR}
mkdir -p ${LOGDIR}
cd $BuildRoot/fpc
echo "building non cross fpc for target $CPU-$OS in $DESTDIR"
echo "see logs in $LOGDIR"
${MAKE} clean all > ${LOGDIR}snapbuild-${CPU}-${OS} 2>&1
${MAKE} install INSTALL_PREFIX=${DESTDIR} LIBDIR=${BASELIBDIR}/${CPU}-${OS} OPT="-Xd -Xt -gl" > ${LOGDIR}snapinstalllog-${CPU}-${OS} 2>&1
# save samplecfg, ppc386
mkdir -p $BinDir
cp ${DESTDIR}lib/fpc/$CompilerVersionStr/samplecfg $BinDir
cp ${DESTDIR}lib/fpc/$CompilerVersionStr/ppc* $BinDir
fi
#===============================================================================
# build ~/.fpc.cfg
if [ $CreateFPCCfg = "yes" ]; then
echo "building ~/fpc.cfg ..."
DestDir=~/freepascal
$BuildRoot/bin/samplecfg $BuildRoot/binutils/cross/destination/lib/fpc/$CompilerVersionStr/ $DestDir
FPCCfg=$DestDir/fpc.cfg
# add -FD and -XP entry for cross compiling
echo "# set binutils paths for crosscompiling" >> $FPCCfg
echo "#IFDEF FPC_CROSSCOMPILING" >> $FPCCfg
echo " -FD${BinDir}" >> $FPCCfg
echo ' -XP$fpctarget-' >> $FPCCfg
echo "#ENDIF" >> $FPCCfg
# test the fpc.cfg
echo "Testing compiling test.pas ..."
TestPas="$BuildRoot/test.pas"
echo "program Test;" > $TestPas
echo "{$mode objfpc}{$H+}" >> $TestPas
echo "uses Classes, SysUtils;" >> $TestPas
echo "begin" >> $TestPas
echo " writeln('Test');" >> $TestPas
echo "end." >> $TestPas
cd $BuildRoot
$BinDir/$CompilerName test.pas
if [ $InstallAsDefault = "yes" ]; then
echo "Installing ~/fpc.cfg ..."
cp $BuildRoot/fpc.cfg ~/.fpc.cfg
fi
fi
# end.