#!/bin/ksh -p
# (note we use "/bin/ksh -p" for Linux/pdksh support in this script)

########################################################################
#                                                                      #
#               This software is part of the ast package               #
#                   Copyright (c) 2012 Roland Mainz                    #
#                      and is licensed under the                       #
#                 Eclipse Public License, Version 1.0                  #
#                    by AT&T Intellectual Property                     #
#                                                                      #
#                A copy of the License is available at                 #
#          http://www.eclipse.org/org/documents/epl-v10.html           #
#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
#                                                                      #
#                                                                      #
#                 Roland Mainz <roland.mainz@nrubsig.org>              #
#                                                                      #
########################################################################

#
# Copyright (c) 2012, Roland Mainz. All rights reserved.
#

#
# buildpcc.sh - pcc compiler standalone build script for the 
# OpenSolaris OS/Net project
#

function fatal_error
{
	print -u2 "${progname}: $*"
	exit 1
}

set -o errexit
set -o xtrace

typeset progname="$(basename "${0}")"
typeset buildmode="$1"

if [[ "${buildmode}" == '' ]] ; then
	fatal_error 'buildmode required.'
fi

# Make sure we use the C locale during building to avoid any unintended
# side-effects
export LANG='C'
export LC_ALL="$LANG" LC_MONETARY="$LANG" LC_NUMERIC="$LANG" LC_MESSAGES="$LANG" LC_COLLATE="$LANG" LC_CTYPE="$LANG"
# Make sure the POSIX/XPG6 tools are in front of /usr/bin (/bin is needed for Linux after /usr/bin)
export PATH='/usr/xpg6/bin:/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/bin:/opt/SUNWspro/bin'

# create a wrapper script
function printf_wrappercmd
{
	typeset cmd="$1"
	shift
	{
		printf '#!%s\n' "${ksh93}"
		printf "$@"
	} >"${cmd}"
	chmod a+rx "${cmd}"
	return 0
}

#
# unpack sources
#
function unpack_sources
{
	rm -Rf "${config.pcclibs_dir}"
	rm -Rf "${config.pcc_dir}"

	case "$1" in
		'tgz')
			for i in "${config.sources[@]}" ; do
				gunzip -c <"$i" | pax -r
			done
			;;
		'cvs')
			cvs -d :pserver:anonymous@pcc.ludd.ltu.se:/cvsroot co pcc pcc-libs
			;;
	esac
	[[ -d "${config.pcclibs_dir}" ]] || fatal_error "${config.pcclibs_dir} not found.\n"
	[[ -d "${config.pcc_dir}"     ]] || fatal_error "${config.pcc_dir} not found.\n"
	return 0
}


#
# run compiler test
#
function compiler_test
{
cat >'x.c' <<EOF
	#include <stdlib.h>
	#include <stdio.h>
	
	int main(int ac, char *av[])
	{
	        puts("hello world chicken");
	        return EXIT_SUCCESS;
	}
EOF
	
	pcc x.c -o './x'
	
	ldd  './x'
	file './x'
	
	printf $"# test begin\n"
	./x || true
	printf $"# test end\n"
	return 0
}

set -o xtrace
set -o errexit
set -o nounset

builtin chmod
builtin mkdir
builtin uname # mandatory
builtin rm

# configuration data
compound -r config=(
	tmpbin="${PWD}/bin"
	pccinstallationdir="${HOME}/pccinstall"
	typeset -a sources=(
		'pcc-libs-20120810.tgz'
		'pcc-20120810.tgz'
	)
	pcclibs_dir='pcc-libs'
	pcc_dir='pcc'
	mode="$1"
)

ksh93="${HOME}/bin/ksh"

export PATH="$(export PATH='/usr/xpg6/bin:/usr/bin' ; getconf 'PATH')"

rm -Rf "${config.pccinstallationdir}"
rm -f 'compile.log'



unpack_sources 'cvs'

#
# apply patches
#
# note this needs GNU patch which is available as
# /usr/gnu/bin on Solaris 11
#
{
cat <<EOF
--- os/sunos/ccconfig.h Fri Aug 10 21:54:55 2012
+++ os/sunos/ccconfig.h  Fri Aug 10 21:55:12 2012
@@ -51,7 +51,7 @@
 #endif
 
 /* host-independent */
-#define	DYNLINKER { "-Bdynamic", "/usr/lib/ld.so", NULL }
+#define	DYNLINKER { "-Bdynamic", "/usr/lib/ld.so.1", NULL }
 
 #if defined(mach_i386)
 #define	CPPMDADD { "-D__i386__", "-D__i386", NULL, }

EOF
} | (cd "${config.pcc_dir}" ; export PATH='/usr/gnu/bin:/usr/bin' ; patch -p0)

#
# create wrapper scripts
#
mkdir -p "${config.tmpbin}"

case "${config.mode}" in
	'Linux.32bit')
		printf_wrappercmd "${config.tmpbin}/gccm32"        "%s" $'gcc -m32 "$@" -Wno-error\n'
		printf_wrappercmd "${config.tmpbin}/ld_b_elf_i386" "%s" $'ld -m elf_i386 "$@"\n'
		printf_wrappercmd "${config.tmpbin}/as32"          "%s" $'as --32 "$@"\n'
		;;
	'Linux.64bit')
		printf_wrappercmd "${config.tmpbin}/gccm64"        "%s" $'gcc -m64 "$@" -Wno-error\n'
		;;
	'SunOS.32bit')
		# we need this to force C99 mode 
		printf_wrappercmd "${config.tmpbin}/suncc99" "%s" $'/opt/SUNWspro/bin/cc -xc99=%all -D_XOPEN_SOURCE=600 -D__EXTENSIONS__=1 "$@"\n'
		;;
	*)
		fatal_error 'Illegal build mode.'
		;;
esac

# build environment
export PATH="${config.tmpbin}:${PATH}"


case "${config.mode}" in
	'Linux.32bit')
		export CC="${config.tmpbin}/gccm32" 
		;;
	'Linux.64bit')
		export CC="${config.tmpbin}/gccm64" 
		;;
	'SunOS.32bit')
		export CC="${config.tmpbin}/suncc99" 
		;;
	*)
		fatal_error 'Illegal build mode.'
		;;
esac


# build options
typeset -a pcclibs_configure_options=(
		"--prefix=${config.pccinstallationdir}"
)

typeset -a pcc_configure_options=(
		"--prefix=${config.pccinstallationdir}"
)

case "${config.mode}" in
	'Linux.32bit')
		pcclibs_configure_options+=( '--build=i386-pc-linux-gnu'	)
		pcclibs_configure_options+=( '--host=i386-pc-linux-gnu'		)
		pcclibs_configure_options+=( '--target=i386-pc-linux-gnu'	)

		pcc_configure_options+=( '--build=i386-pc-linux-gnu'	)
		pcc_configure_options+=( '--host=i386-pc-linux-gnu'	)
		pcc_configure_options+=( '--target=i386-pc-linux-gnu'	)
		pcc_configure_options+=( "--with-assembler=${config.tmpbin}/as32"	)
		pcc_configure_options+=( "--with-linker=${config.tmpbin}/ld_b_elf_i386"	)
		;;
	'Linux.64bit')
		;;
	'SunOS.32bit')
		;;
esac


#
# build pcc-libs
#
{
	cd "${config.pcclibs_dir}"

	${ksh93} ./configure "${pcclibs_configure_options[@]}"

	gmake clean

	gmake

	gmake install

	cd '..'
} 2>&1 | tee -a 'compile.log'

#
# build pcc itself
#
{
	cd "${config.pcc_dir}"

	${ksh93} ./configure "${pcc_configure_options[@]}"

	gmake clean

	gmake

	gmake install

	cd '..'
} 2>&1 | tee -a 'compile.log'

export PATH="${config.pccinstallationdir}/bin:$PATH"
[[ -x "${config.pccinstallationdir}/bin/pcc" ]] || { print -u2 $"pcc not found." ; exit 1 ; }



compiler_test

exit 0
# EOF.
