#!/bin/csh -f

####################################################################################
#  File      : build.csh
#  Created   : Thu Jan 27 09:50:55 2005
#  Author    : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
#  Project   : SALOME
#  Module    : Installation Wizard
#  Copyright : 2002-2007 CEA
#
#  This script is the part of the SALOME installation procedure.
#
#  This script can be used to build and install SALOME modules from sources.
#  Try build.csh -h for more details about usage.
#
####################################################################################

set is_build_configure=0
set is_configure=0
set med_with_gui=1
set is_delete=0
set verbose_level=2
set params=""
set b_params=""
set modules=(KERNEL GUI GEOM MED SMESH VISU SUPERV NETGENPLUGIN GHS3DPLUGIN COMPONENT PYCALCULATOR CALCULATOR HELLO PYHELLO LIGHT)
set optim=""
set is_install=0
set is_help=0
set is_tui=0
set prefix=""

#########################################################
# parse parameters
#########################################################
while ( ${%1} > 0 )
    if ( "$1" == "-b" ) then
	set is_build_configure=1
	set is_configure=1
    else if ( "$1" == "-c" ) then
	set is_configure=1
    else if ( "$1" == "-w" ) then
	set med_with_gui=0
    else if ( "$1" == "-d" ) then
	set is_delete=1
    else if ( "$1" == "-o" ) then
	set optim="--enable-production=yes --disable-debug"
    else if ( "$1" == "-i" ) then
	set is_install=1
    else if ( "$1" == "-v" ) then
	shift
	set verbose_level=$1
    else if ( "$1" == "-p" ) then
	shift
	set is_install=1
	set prefix=$1
    else if ( "$1" == "-h" ) then
	set is_help=1
    else if ( "$1" == "-t" ) then
	set is_tui=1
    else
	set ckt=`echo ${modules} | grep $1`
	if ( "$ckt" != "" ) then
	    set params="$params $1"
	else
	    set b_params="$b_params $1"
	    echo "\!\!\! Warning \!\!\! Unknown module: $1. Skipping."
	endif
    endif
    shift
end

#########################################################
# if -h option is given - print help info and exit 
#########################################################
if ( $is_help == 1 ) then
echo ""
echo ""
echo "Description:"
echo "            Builds given SALOME modules by performing make and (optionally) make install commands"
echo ""
echo "Usage:"
echo "            build.csh [ <option> ] ... [ <module> [ <module> ... ] ]"
echo ""
echo "<module>    Modules to build, separated by space(s)."
echo "            If no modules are given - all SALOME modules are assumed."
echo "            Note, that modules given in command lines are automatically sorted in such order"
echo "            to support correct modules dependencies."
echo ""
echo "Options:"
echo "-b          Perform build_configure command for all given modules."
echo "            This option forces configure (-c) key to be set. Default is off."
echo ""
echo "-c          Perform configure command for all given modules. Default is off."
echo ""
echo "-w          Add --without-ihm key to build_configure and configure"
echo "            commands for MED module to build its sources without GUI."
echo "            By default MED sources are built with GUI."
echo ""
echo "-d          Delete build directories before calling configure, to enforce full rebuild"
echo "            (and reinstall if -i or -p option is used) of module."
echo "            Use this option carefully."
echo ""
echo "-o          Build sources in optimized mode. Default is off that means debug mode."
echo "            Use this option together with -c or -b."
echo "            This option can require -d option to be set (to ensure that previously"
echo "            created build directories are removed to enforce rebuild in optimized mode)."
echo ""
echo "-t          Performs make dev_docs step to build TUI documentation for those modules"
echo "            which support this. Default is off."
echo ""
echo "-i          Performs make install step. Default is off that means only make step."
echo ""
echo "-p <prefix> Define the directory where to install modules after compilation."
echo "            By default the directory where compilation is performed is used."
echo ""
echo "-v <level>  Verbose level (0-2, default 2): print information on build status:"
echo "            0: only 'make' errors"
echo "            1: 0 + compiler and other errors (including build_configure, configure)"
echo "            2: 1 + compiler and other warnings "
echo ""
echo "-h          Prints this help information."
echo ""
echo "Note:       If no keys are given script just performs make step."
echo ""
echo "Example:"
echo "            ./build.csh -o -i -b KERNEL MED GEOM"
echo ""
echo "            This will make KERNEL, GEOM and MED modules: build_configure, configure, make"
echo "            and install procedures will be performed for all specified modules."
echo "            The modules will be built in the optimized mode"
echo ""
exit
endif

#########################################################
# sort modules in proper order according to the dependancies
#########################################################
if ( "${params}" != "" ) then
    set xparams=""
    foreach module (${modules})
	set ckt=`echo ${params} | grep ${module}`
	if ( "$ckt" != "" ) then
	    set xparams="$xparams $module"
	endif
    end
    set modules=($xparams)
else
    if ( "${b_params}" != "" ) then
	echo "Nothing to be built. Exiting."
	exit
    endif
endif

echo ">>> The following SALOME packages will be built:"
echo $modules

#########################################################
# set environment
#########################################################
set env_script=`dirname $0`/env_build.csh
if ( ! -e $env_script ) then
    set env_script=`dirname $0`/env_products.csh
endif
if ( -e $env_script ) then
    echo ">>> Setting environment"
    source $env_script
else
    echo "\!\!\! Warning \!\!\! Environment is not set: file env_products.csh is not found."
endif

set BUILD_DIR=${PWD}
set LOG_DIR=${BUILD_DIR}/LOGS

#########################################################
# define installation prefix
#########################################################
if ( "$prefix" == "" ) then
    set prefix=${BUILD_DIR}/INSTALL
    if ( $is_install == 1 ) then
	echo "\!\!\! Warning \!\!\! Installation directory is not set."
	echo "All the modules will be installed to the $prefix"
    else
	set is_kernel=`echo ${modules} | grep KERNEL`
	if ( "$is_kernel" != "" ) then
	    echo "\!\!\! Warning \!\!\! KERNEL module requires install step to be performed."
	    echo "For this module -i option will be forced."
	    echo "The module(s) will be installed to the $prefix"
	endif
    endif
else
    set is_absolute=`echo $prefix | grep -e "^/"`
    if ( "$is_absolute" == "" ) then
	set prefix=${BUILD_DIR}/$prefix
	echo "\!\!\! Warning \!\!\! Relative prefix is used."
	echo "All the modules will be installed to the $prefix"
    endif
endif

#########################################################
# create log directory
#########################################################
if ( ! -e ${LOG_DIR} ) then
    mkdir -p ${LOG_DIR}
endif

echo "==========================================================================="
echo "Starting SALOME build at `date`"
echo "==========================================================================="

#########################################################
# loop for all given modules
#########################################################
foreach module (${modules})
  echo ">>> Processing ${module} module"

  set module_src=`printenv ${module}_SRC_DIR`
  set module_build=${BUILD_DIR}/${module}_BUILD

  if ( ${module_src} != "" ) then
    set add_keys=""
    cd ${BUILD_DIR}
    #########################################################
    # check if sources directory exists
    #########################################################
    if ( ! -e ${module_src} ) then
	echo "\!\!\! Error \!\!\! Can't find sources directory: ${module_src} does not exist."
	continue
    endif
    #########################################################
    # check if configure script exists
    #########################################################
    set cfg_exist=0
    if ( -e ${module_src}/configure ) then
	set cfg_exist=1
    endif
    #########################################################
    # perform build_configure if -b flag is given or if 
    # configure script does not exist (first compilation?)
    #########################################################
    if ( $is_build_configure == 1 || $cfg_exist == 0 ) then
	echo "... Performing build_configure"
	#########################################################
	# check if build_configure script exists
	#########################################################
	if ( ! -e ${module_src}/build_configure ) then
	    echo "\!\!\! Warning \!\!\! Can not find build_configure script in ${module_src}."
	else
	    #########################################################
	    # call build_configure
	    #########################################################
	    if ( $med_with_gui == 0 && "${module}" == "MED" ) then
		set add_keys="--without-ihm"
	    endif
	    cd ${module_src}
	    ./build_configure ${add_keys} >& ${LOG_DIR}/build_configure_${module}.log
	    #########################################################
	    # echo possible errors
	    #########################################################
	    if ( $verbose_level > 0 ) then
		cat ${LOG_DIR}/build_configure_${module}.log | grep -E "(failed|: error:)" > /dev/stderr
	    endif
	endif
    endif
    #########################################################
    # deleting build directory if -d flag is given
    #########################################################
    if ( -e ${module_build} && $is_delete == 1 ) then
	echo "... Removing ${module_build}"
	rm -rf ${module_build}
    endif
    #########################################################
    # creating build directory if it does not exist
    #########################################################
    if ( ! -e ${module_build} ) then
	mkdir -p ${module_build}
    endif
    cd ${module_build}
    #########################################################
    # check if top Makefile exists in build directory, i.e. 
    # is it necessary to run configure script
    #########################################################
    set mkfile_exist=0
    if ( -e ${module_build}/Makefile ) then
	set mkfile_exist=1
    endif
    #########################################################
    # check if configure options are changed from the 
    # previous launch
    #########################################################
    set opts_changed=0
##    if ( -f ${module_build}/config.log ) then
##	set old_prefix=`grep -e '^prefix=' ${module_build}/config.log | sed -e "s%^prefix='\(.*\)'%\1%"`
##	if ( "$old_prefix" != "$prefix" ) then
##	    set opts_changed=1
##	endif
##    endif
    #########################################################
    # define installation directory (by using module's version
    # number); default is a build directory
    #########################################################
    set vx=""
    set cfg_file=configure.ac
    if ( ! -e ${module_src}/${cfg_file} ) then
	set cfg_file=configure.in.base
    endif
    if ( -e ${module_src}/${cfg_file} ) then
	set vx=`grep -e "^VERSION=" ${module_src}/${cfg_file} | awk -F= '{ if (NF>1) print $NF; }' | tr -d '[:space:]'`
    endif
    set px=${BUILD_DIR}/${module}
    if ( "$prefix" != "" ) then
	set px=$prefix/${module}
    endif
    if ( "$vx" != "" ) then
	set px="$px"_"$vx"
    endif
    #########################################################
    # perform configure if -c flag is given or if 
    # Makefile does not exist (first compilation?)
    #########################################################
    if ( $is_configure == 1 || $mkfile_exist == 0 || $opts_changed == 1 ) then
	echo "... Performing configure"
	#########################################################
	# check if configure script exists
	#########################################################
	if ( ! -e ${module_src}/configure ) then
	    echo "\!\!\! Warning \!\!\! Can not find configure script in ${module_src}."
	else
	    if ( $med_with_gui == 0 && "${module}" == "MED" ) then
		set add_keys="--without-ihm"
	    endif
	    if ( "${module}" == "NETGENPLUGIN" && ($?NETGENHOME) ) then
		set add_keys="--with-netgen=${NETGENHOME}"
	    endif
	    ${module_src}/configure --prefix=$px ${optim} ${add_keys} >& ${LOG_DIR}/configure_${module}.log
	    #########################################################
	    # echo possible errors
	    #########################################################
	    if ( $verbose_level > 0 ) then
		cat ${LOG_DIR}/configure_${module}.log | grep ": error:" > /dev/stderr
	    endif
	    if ( $verbose_level > 1 ) then
		cat ${LOG_DIR}/configure_${module}.log | grep ": WARNING:" > /dev/stderr
	    endif
	endif
    endif
    #########################################################
    # perform make
    #########################################################
    echo "... Performing make"
    #########################################################
    # first clear dependencies
    #########################################################
    find . -name ".dep*" -type f -exec rm -f {} \; >& /dev/null
    make >& ${LOG_DIR}/make_${module}.log
    set sts=$status
    #########################################################
    # if make step is successful set the ${module}_ROOT_DIR
    # environment variable
    #########################################################
    if ( $sts == 0 ) then
	setenv ${module}_ROOT_DIR ${module_build}
    endif
    #########################################################
    # print make errors
    #########################################################
    cat ${LOG_DIR}/make_${module}.log | grep '[*][*][*]' > /dev/stderr
    #########################################################
    # print compiler errors and warnings
    # Note: here awk is used to concatenate together several lines of single
    #       error or warning message produced by stupid gnu compiler
    # Actually, instead of that we could use 'fmessage length=n' option of g++...
    #########################################################
    if ( $verbose_level > 0 ) then
	###cat ${LOG_DIR}/make_${module}.log | grep ": error"
	cat ${LOG_DIR}/make_${module}.log | awk 'substr($0,0,1)!=" " {print ""} {printf $0} END {print ""}' | grep "${module_src}/[A-Za-z_0-9./]*:" | sed s@"^${module_src}/src/"@@ > /dev/stderr
    endif
    if ( $verbose_level > 1 ) then
	cat ${LOG_DIR}/make_${module}.log | awk 'substr($0,0,1)!=" " {print ""} {printf $0} END {print ""}' | grep ": warning" | sed s@"^${module_src}/src/"@@ > /dev/stderr
    endif
    #########################################################
    # perform make dev_docs step if -t flag is given
    #########################################################
    if ( $is_tui == 1 && $sts == 0 && -d ${module_build}/doc ) then
	cd ${module_build}/doc
	set dd=`cat Makefile | grep -E "dev_docs[[:space:]]*:"`
	if ( "$dd" != "" ) then
	    echo "... Performing make dev_docs"
	    make dev_docs >& ${LOG_DIR}/make_dev_docs_${module}.log
	    cat ${LOG_DIR}/make_dev_docs_${module}.log | grep '[*][*][*]' > /dev/stderr
	endif
    endif
    cd ${module_build}
    #########################################################
    # perform make if -i or -p flags are given
    #########################################################
    if ( $is_install == 1 && $sts == 0 || "${module}" == "KERNEL" ) then
	#########################################################
	# deleting build directory if -d flag is given
	#########################################################
	if ( -e $px && $is_delete == 1 ) then
	    echo "... Removing $px"
	    rm -rf $px
	endif
	echo "... Performing make install"
	make install >& ${LOG_DIR}/make_install_${module}.log
	set sts=$status
	#########################################################
	# if make install step is successful set the 
        # ${module}_ROOT_DIR environment variable
	#########################################################
	if ( $sts == 0 ) then
	    setenv ${module}_ROOT_DIR $px
	endif
    endif
    echo ">>> Finished ${module} module"
  else
    echo "\!\!\! Error \!\!\! Can't find module sources. ${module}_SRC_DIR environment variable is not set."
  endif
end
#########################################################
# finalize
#########################################################
cd ${BUILD_DIR}

echo "==========================================================================="
echo "SALOME build finished at `date`"
echo "==========================================================================="
