#!/bin/sh

# Ensure we run from the repository root regardless of where the script is called from
cd "$(dirname "$0")" || exit 1

libs="unix.cma"

OCAMLC="ocamlc -g -I +unix"
OCAMLVER=$($OCAMLC -version)
echo "$OCAMLVER"

ocaml configure.ml


extmodules="compat location fugue string_utils filepath filesystem cli"
coremodules="types gconf filetype dag libname pp expr utils modname taskdep helper dagutils process findlibConf scheduler prog dependencies generators hier meta metacache obuild_lexer obuild_ast obuild_parser target dist project obuild_validate project_read analyze configure prepare_types ppx_resolver prepare buildprogs build_cstubs build exception"
commandmodules="sdist doc init help install"
mainmodules="path_generated main"

set -e

########################################################################
########################################################################
########################################################################
# build lib (combining base utilities, core library, and command modules)
cd lib/
rm -f ./*.cmi ./*.cmo ./*.o
rm -f base/*.cmi base/*.cmo base/*.o
rm -f core/*.cmi core/*.cmo core/*.o

# Compile base modules as top-level (for bootstrap compatibility)
cd base
for mod in $extmodules
do
	echo "COMPILING base/$mod"
	[ -f "${mod}.mli" ] && $OCAMLC -c "${mod}.mli"
	$OCAMLC -c "${mod}.ml"
done;
cd ..

# Compile core modules (can access base modules directly)  
cd core
for mod in $coremodules
do
	echo "COMPILING core/$mod"
	[ -f "${mod}.mli" ] && $OCAMLC -I .. -I ../base -c "${mod}.mli"
	$OCAMLC -I .. -I ../base -c "${mod}.ml"
done;
cd ..

# Compile command modules
for mod in $commandmodules
do
	echo "COMPILING command/$mod"
	[ -f "${mod}.mli" ] && $OCAMLC -I . -I base -I core -c "${mod}.mli"
	$OCAMLC -I . -I base -I core -c "${mod}.ml"
done;

# During bootstrap, copy all modules to root for main.ml compatibility
cd ..
echo "COPYING modules to root for bootstrap"
cp lib/base/*.cmo ./
cp lib/base/*.cmi ./
cp lib/core/*.cmo ./
cp lib/core/*.cmi ./
cp lib/*.cmo ./
cp lib/*.cmi ./

# then bootstrap the main executable
# main needs the version number

cat <<EOF > src/path_generated.ml

(* autogenerated file by bootstrap. do not modify *)

let project_version = "0.0.0"

EOF
cd src
MAINCMO=""
for mod in $mainmodules
do
	echo "COMPILING $mod"
	[ -f "${mod}.mli" ] && $OCAMLC -I ../ -c "${mod}.mli"
	$OCAMLC -I ../ -c "${mod}.ml"
	MAINCMO="$MAINCMO ${mod}.cmo"
done
echo "LINKING obuild.bootstrap"
# Link with all individual .cmo files for bootstrap
ALLCMO=""
for mod in $extmodules; do ALLCMO="$ALLCMO ${mod}.cmo"; done
for mod in $coremodules; do ALLCMO="$ALLCMO ${mod}.cmo"; done
for mod in $commandmodules; do ALLCMO="$ALLCMO ${mod}.cmo"; done
$OCAMLC -o ../obuild.bootstrap -I ../ ${libs} $ALLCMO $MAINCMO
cd ..

rm -f lib/*.cmi lib/*.cmo lib/*.o
rm -f lib/base/*.cmi lib/base/*.cmo lib/base/*.o
rm -f lib/core/*.cmi lib/core/*.cmo lib/core/*.o
rm -f src/*.cmi src/*.cmo src/*.o
rm -f ./*.cmi ./*.o ./*a ./*.cmo
rm -f src/path_generated.ml

########################################################################
########################################################################
########################################################################

# rebuild everything with the bootstraped version
export OCAMLRUNPARAM=b
./obuild.bootstrap clean
if [ -x "$(command -v ocamlopt)" ]; then
	./obuild.bootstrap configure
	./obuild.bootstrap build
else
	./obuild.bootstrap configure \
		--executable-native=false \
		--library-native=false \
		--library-plugin=false \
		--executable-bytecode=true \
		--library-bytecode=true
	./obuild.bootstrap build
	mv dist/build/obuild/obuild.byte dist/build/obuild/obuild
fi
if [ -x dist/build/obuild/obuild ]; then
	rm obuild.bootstrap
fi
