#!/bin/sh
[ "$BASH" ] || exec bash `which $0` ${1+"$@"}
#
# ---------------------------------------------------------------
# Copyright 2003 Przemyslaw Czerpak <druzus@priv.onet.pl>
# simple script to build binaries .tgz from xHarbour sources
#
# See doc/license.txt for licensing terms.
# ---------------------------------------------------------------
#

# set environment variables
export HB_ARCHITECTURE="linux"
export HB_COMPILER="gcc"
[ -z "${HB_BIN_INSTALL}" ] && export HB_BIN_INSTALL="/usr/bin"
[ -z "${HB_INC_INSTALL}" ] && export HB_INC_INSTALL="/usr/include/xharbour"
[ -z "${HB_LIB_INSTALL}" ] && export HB_LIB_INSTALL="/usr/lib64/xharbour"

# be sure that xharbour binaries are in your path
export PATH="${HB_BIN_INSTALL}:${PATH}"

if [ "${HB_COMPILER}" == "gpp" ]; then
   HB_CC="g++"
else
   HB_CC="gcc"
fi

if [ $# = 0 ]; then
    echo "syntax: $0 [<options,...>] <file>[.prg|.o]

\"xhbcc\", \"xhbcmp\", \"xhblnk\" and \"xhbmk\" parameters:
    -o<outputfilename>  # output file name
\"xhblnk\" and \"xhbmk\" parameters:
    -static             # link with static xharbour libs
    -fullstatic         # link with all static libs
    -shared             # link with shared libs (default)
    -mt                 # link with multi-thread libs
    -gt<hbgt>           # link with <hbgt> GT driver, can be repeated to
                        # link with more GTs. The first one will be
                        #      the default at runtime
    -xbgtk              # link with xbgtk library (xBase GTK+ interface)
    -xhgtk              # link with xHGtk library (GTK+ interface)
    -hwgui              # link with HWGUI library (GTK+ interface)
    -l<libname>         # link with <libname> library
    -L<libpath>         # additional path to search for libraries
    -fmstat             # link with the memory statistics lib
    -nofmstat           # do not link with the memory statistics lib (default)
    -[no]strip          # strip (no strip) binaries
    -main=<main_func>   # set the name of main program function/procedure.
                        # if not set then 'MAIN' is used or if it doesn't
                        # exist the name of first public function/procedure
                        # in first linked object module (link)
"
    exit 1
elif [ "$*" = "mk-links" ]; then
    DIR="${0%/*}"
    NAME="${0##*/}"
    if [ "${DIR}" != "${NAME}" ]; then
        (cd "${DIR}"
        for n in xhbcc xhbcmp xhbmk xhblnk; do
            if [ "${HB_ARCHITECTURE}" = "dos" ]; then
                cp -f "${NAME}" "${n}"
            else
                ln -sf "${NAME}" "${n}"
            fi
        done
        )
    fi
    exit
fi

## check basename
case "${0##*/}" in
    *cc)    HB=cc  ;;
    *cmp)   HB=cmp ;;
    *lnk)   HB=lnk ;;
    *mk)    HB=mk  ;;
    *)      exit 1 ;;
esac

## default parameters
HB_STATIC="no"
HB_MT=""
HB_GT="trm"

HB_GPM_MOUSE=""

HB_GT_REQ=""
HB_FM_REQ=""
HB_STRIP="yes"
HB_MAIN_FUNC=""
HB_XBGTK=""
HB_XHGTK=""
HB_HWGUI=""
HB_USRLIBS=""
HB_USRLPATH=""
HB_GEN=""
[ -n "$TMPDIR" ] || TMPDIR="$TMP"
[ -n "$TMPDIR" ] || TMPDIR="$TEMP"
[ -n "$TMPDIR" ] || TMPDIR="/tmp"
_TMP_FILE_="${TMPDIR}/hb-build-$USER-$$.c"

## parse params
P=( "$@" ); n=0; DIROUT="."; FILEOUT=""
while [ $n -lt ${#P[@]} ]; do
    v=${P[$n]}; p=""
    case "$v" in
        -o*)
            d="${v#-o}"; p="${v}"
            if [ -d "${d}" ]; then
                DIROUT="${d%/}"
            elif [ -d "${d%/*}" ]; then
                DIROUT="${d%/*}"; FILEOUT="${d##*/}"; p="-o${d}"
                [ ${HB} = "cc" ] || p="-o${d%.*}"
            elif [ -n "${d}" ]; then
                FILEOUT="${d}"; p="-o${d}"
                [ ${HB} = "cc" ] || p="-o${d%.*}"
            fi ;;
        -static)     HB_STATIC="yes" ;;
        -fullstatic) HB_STATIC="full" ;;
        -shared)     HB_STATIC="no" ;;
        -xbgtk)      HB_XBGTK="yes" ;;
        -xhgtk)      HB_XHGTK="yes" ;;
        -hwgui)      HB_HWGUI="yes" ;;
        -mt)         HB_MT="MT" ;;
        -gt*)        HB_GT_REQ="${HB_GT_REQ} ${v#-gt}" ;;
        -fmstat)     HB_FM_REQ="STAT" ;;
        -nofmstat)   HB_FM_REQ="NOSTAT" ;;
        -strip)      HB_STRIP="yes" ;;
        -nostrip)    HB_STRIP="no" ;;
        -l[^-]*)     HB_USRLIBS="${HB_USRLIBS} ${v}" ;;
        -L[^-]*)     HB_USRLPATH="${HB_USRLPATH} ${v}" ;;
        -main=*)     HB_MAIN_FUNC="${v#*=}" ;;
        -g[cohwij])  HB_GEN="${v#-g}"; p="${v}" ;;
        -gc[0-9])    HB_GEN="c"; p="${v}" ;;
        -go[0-9])    HB_GEN="o"; p="${v}" ;;
        -*)          p="${v}" ;;
        *)           [ -z ${FILEOUT} ] && FILEOUT="${v##*/}"; p="${v}" ;;
    esac
    [ -n "$p" ] && PP[$n]="$p"
    n=$[$n + 1]
done
P=( "${PP[@]}" )

case "${HB_MT}" in
    [Mm][Tt]|[Yy][Ee][Ss]|1)  HB_MT="MT";;
    *)  HB_MT="";;
esac

SYSTEM_LIBS="-lm -ldl -lrt"
# use pthread system library for MT programs
if [ "${HB_MT}" = "MT" ]; then
    case "${HB_ARCHITECTURE}" in
        dos|w32|os2)
            ;;
        *)
            SYSTEM_LIBS="-lpthread ${SYSTEM_LIBS}"
            ;;
    esac
fi

HB_GT_STAT=""
[ -z "${HB_GT_REQ}" ] && HB_GT_REQ="${HB_GT}"
HB_GT_REQ=`echo ${HB_GT_REQ}|tr '[a-z]' '[A-Z]'`
HB_MAIN_FUNC=`echo ${HB_MAIN_FUNC}|tr '[a-z]' '[A-Z]'`

HB_PATHS="-I${HB_INC_INSTALL}"
GCC_PATHS="${HB_PATHS} -L${HB_LIB_INSTALL}"

LN_OPT=""
CC_OPT=" -fPIC"
HB_OPT=""
[ "${HB_GEN}" != "" ] || HB_OPT="${HB_OPT} -gc0"

HB_GPM_LIB=""
if [ -f "${HB_LIB_INSTALL}/libgtsln.a" ]; then
    if [ "${HB_ARCHITECTURE}" = "darwin" ]; then
        SYSTEM_LIBS="${SYSTEM_LIBS} -L/sw/lib -L/opt/local/lib"
    elif [ "${HB_ARCHITECTURE}" = "bsd" ]; then
        SYSTEM_LIBS="${SYSTEM_LIBS} -L/usr/local/lib"
    fi
    SYSTEM_LIBS="-lslang ${SYSTEM_LIBS}"
    [ "${HB_GPM_MOUSE}" = "yes" ] && HB_GPM_LIB="gpm"
fi
if [ -f "${HB_LIB_INSTALL}/libgtcrs.a" ]; then
    SYSTEM_LIBS="-lncurses ${SYSTEM_LIBS}"
    [ "${HB_GPM_MOUSE}" = "yes" ] && HB_GPM_LIB="gpm"
fi
if [ "${HB_WITHOUT_X11}" != "yes" ]; then
    if [ -f "${HB_LIB_INSTALL}/libgtxvt.a" ] || [ -f "${HB_LIB_INSTALL}/libgtxwc.a" ]; then
        [ -d "/usr/X11R6/lib64" ] && SYSTEM_LIBS="${SYSTEM_LIBS} -L/usr/X11R6/lib64"
        SYSTEM_LIBS="-L/usr/X11R6/lib -lX11 ${SYSTEM_LIBS}"
    fi
fi
[ -n "${HB_GPM_LIB}" ] && SYSTEM_LIBS="-l${HB_GPM_LIB} ${SYSTEM_LIBS}"


if [ "${HB_STATIC}" = "no" ]; then
    SYSTEM_LIBS=""
fi

if [ "${HB_XBGTK}" = "yes" ]; then
    SYSTEM_LIBS="${SYSTEM_LIBS} `pkg-config --libs gtk+-2.0`"
elif [ "${HB_XHGTK}" = "yes" ]; then
    SYSTEM_LIBS="${SYSTEM_LIBS} `pkg-config --libs gtk+-2.0 libglade-2.0`"
elif [ "${HB_HWGUI}" = "yes" ]; then
    SYSTEM_LIBS="${SYSTEM_LIBS} `pkg-config --libs gtk+-2.0 --libs libgnomeprint-2.2`"
fi

if [ "${HB_STATIC}" = "full" ]; then
    if [ "${HB_ARCHITECTURE}" = "linux" ]; then
        SYSTEM_LIBS="${SYSTEM_LIBS} -lpthread -ldl"
    fi
    LN_OPT="${LN_OPT} -static"
    HB_STATIC="yes"
fi

HB_LNK_REQ=""
for gt in ${HB_GT_REQ}; do
#    if [ "${HB_STATIC}" = "yes" ] || [ "${gt}" = "ALLEG" ]; then
        HB_LNK_REQ="${HB_LNK_REQ} HB_GT_${gt}"
        if [ "${gt}" = "ALLEG" ]; then
            if [ "${HB_STATIC}" = "yes" ]; then
                SYSTEM_LIBS="`allegro-config --static 2>/dev/null` ${SYSTEM_LIBS}"
            else
                SYSTEM_LIBS="`allegro-config --libs 2>/dev/null` ${SYSTEM_LIBS}"
            fi
        fi
#    fi
done
[ -n "${HB_FM_REQ}" ] && HB_LNK_REQ="${HB_LNK_REQ} HB_FM_${HB_FM_REQ}"

HB_LNK_ATTR=""
HARBOUR_LIBS=""
if [ "${HB_STATIC}" = "yes" ]; then
    libs="vm pp rtl pcrepos rdd dbffpt dbfcdx dbfnsx dbfntx hsx hbsix usrrdd  macro common lang codepage gtcrs gtsln gtxvt gtxwc gtalleg gtcgi gtstd gtpca gttrm zlib  gtwin gtwvt gtgui gtdos gtos2 tip ct cgi hbodbc debug profiler  rddads nf"
else
    l="xharbour"
    if [ "${HB_ARCHITECTURE}" = "darwin" ]; then
        pref="lib"
        ext=".dylib"
        LN_OPT="${LN_OPT} -bind_at_load -multiply_defined suppress"
    elif [ "${HB_ARCHITECTURE}" = "w32" ]; then
        pref=""
        ext=".dll"
        HB_LNK_ATTR="__attribute__ ((dllimport))"
    elif [ "${HB_ARCHITECTURE}" = "hpux" ]; then
        pref="lib"
        ext=".sl"
    else
        pref="lib"
        ext=".so"
    fi
    [ "${HB_MT}" = "MT" ] && [ -f "${HB_LIB_INSTALL}/${pref}${l}mt${ext}" ] && l="${l}mt"
    [ -f "${HB_LIB_INSTALL}/${pref}${l}${ext}" ] && HARBOUR_LIBS="${HARBOUR_LIBS} -l${l}"
    libs="gtalleg hbodbc debug profiler  rddads nf"
fi
for l in ${libs}
do
    [ "${HB_MT}" = "MT" ] && [ -f "${HB_LIB_INSTALL}/lib${l}mt.a" ] && l="${l}mt"
    if [ -f "${HB_LIB_INSTALL}/lib${l}.a" ]; then
        HARBOUR_LIBS="${HARBOUR_LIBS} -l${l}"
    fi
done
if [ "${HB_XBGTK}" = "yes" ]; then
    HARBOUR_LIBS="${HARBOUR_LIBS} -lxbgtk"
    HB_PATHS="${HB_PATHS} -I`PKG_CONFIG_PATH=/usr/local/lib/pkgconfig pkg-config --variable=xbgtkincludedir xbgtk`"
fi
if [ "${HB_XHGTK}" = "yes" ]; then
    HARBOUR_LIBS="${HARBOUR_LIBS} -lxhgtk"
fi
if [ "${HB_HWGUI}" = "yes" ]; then
    HARBOUR_LIBS="${HARBOUR_LIBS} -lhwgui -lprocmisc -lhbxml"
fi
if [ "${HB_ARCHITECTURE}" = "darwin" ] || \
   [ "${HB_ARCHITECTURE}" = "sunos" ] || \
   [ "${HB_ARCHITECTURE}" = "hpux" ]; then
    HARBOUR_LIBS="${HARBOUR_LIBS} ${HARBOUR_LIBS}"
else
    HARBOUR_LIBS="-Wl,--start-group ${HARBOUR_LIBS} -Wl,--end-group"
fi

l="mainwin"
[ "${HB_MT}" = "MT" ] && [ -f "${HB_LIB_INSTALL}/lib${l}mt.a" ] && l="${l}mt"
[ -f "${HB_LIB_INSTALL}/lib${l}.a" ] && HARBOUR_LIBS="${HARBOUR_LIBS} -l${l}"

l="fmstat"
[ "${HB_MT}" = "MT" ] && [ -f "${HB_LIB_INSTALL}/lib${l}mt.a" ] && l="${l}mt"
if [ -f "${HB_LIB_INSTALL}/lib${l}.a" ] && \
   ( [ -n "${HB_FM_REQ}" ] || [ "${HB_STATIC}" = "yes" ] ) && \
   ( [ "${HB_COMPILER}" != "cemgw" ] || [ "${HB_FM_REQ}" = "STAT" ] ); then
    if [ "${HB_STATIC}" = "yes" ] && [ "${HB_FM_REQ}" = "STAT" ]; then
        HARBOUR_LIBS="-l${l} ${HARBOUR_LIBS}"
    else
        HARBOUR_LIBS="${HARBOUR_LIBS} -l${l}"
    fi
fi

if [ "${HB_ARCHITECTURE}" = "darwin" ]; then
    CC_OPT="${CC_OPT} -no-cpp-precomp -Wno-long-double"
elif [ "${HB_ARCHITECTURE}" = "sunos" ]; then
    HB_STRIP="no"
fi

FOUTC="${DIROUT}/${FILEOUT%.*}.c"
FOUTO="${DIROUT}/${FILEOUT%.*}.o"
FOUTE="${DIROUT}/${FILEOUT%.[Pp][Rr][Gg]}"
FOUTE="${FOUTE%.[oc]}"
FOUTE="${FOUTE%}"

hb_cc()
{
    local LNK_OPT P n

    LNK_OPT="${LN_OPT} ${HB_USRLPATH} ${HB_USRLIBS} ${HARBOUR_LIBS} ${SYSTEM_LIBS}"
    P=( "$@" ); n=0
    while [ $n -lt ${#P[@]} ]; do
        if [ "${P[$n]}" = "-c" ]; then
            LNK_OPT=""
            n=${#P[@]}
        fi
        n=$[$n + 1]
    done

    ${HB_CC} "$@" ${CC_OPT} ${GCC_PATHS} ${LNK_OPT}
}

hb_cmp()
{
    harbour "$@" ${HB_OPT} ${HB_PATHS} && \
    ( [ "${HB_GEN//c/}" != "" ] || \
    ( [ -f "${FOUTC}" ] && \
    hb_cc -c "${FOUTC}" -o "${FOUTO}" && \
    ( [ "${HB_GEN}" = "c" ] || rm -f "${FOUTC}" ) ) )
}

hb_link()
{
    if [ "${HB_COMPILER}" != "djgpp" ]; then
        if [ -n "${HB_MAIN_FUNC}" ]; then
            HB_MAIN_FUNC="@${HB_MAIN_FUNC}"
        elif [ -f "${FOUTO}" ]; then
            HB_MAIN_FUNC=`hb_lnk_main "${FOUTO}"`
        fi
    fi
    if [ -n "${HB_LNK_REQ}" ] || [ -n "${HB_GT_REQ}" ] || [ -n "${HB_MAIN_FUNC}" ]; then
        hb_lnk_request > ${_TMP_FILE_}
        LN_OPT="${_TMP_FILE_} ${LN_OPT}"
    fi
    hb_cc "$@" -o "${FOUTE}"
}

hb_lnk_request()
{
    echo "#include \"hbapi.h\""
    if [ -n "${HB_LNK_REQ}" ]; then
        for fn in ${HB_LNK_REQ}; do
            echo "HB_FUNC_EXTERN( ${fn} );"
        done
        echo "void _hb_lnk_ForceLink_build( void )"
        echo "{"
        for fn in ${HB_LNK_REQ}; do
            echo "   HB_FUNC_EXEC( ${fn} );"
        done
        echo "}"
    fi
    gt="${HB_GT_REQ%% *}"
    if [ -n "$gt" ] || [ -n "${HB_MAIN_FUNC}" ]; then
        echo "#include \"hbinit.h\""
        echo "HB_EXTERN_BEGIN"
        echo "extern ${HB_LNK_ATTR} char * s_defaultGT;"
        echo "extern ${HB_LNK_ATTR} char * s_pszLinkedMain;"
        echo "HB_EXTERN_END"
        echo "HB_CALL_ON_STARTUP_BEGIN( hb_lnk_SetDefault_build )"
        if [ -n "$gt" ]; then
            echo "   s_defaultGT = \"$gt\";"
        fi
        if [ -n "${HB_MAIN_FUNC}" ]; then
            echo "   s_pszLinkedMain = \"${HB_MAIN_FUNC}\";"
        fi
        echo "HB_CALL_ON_STARTUP_END( hb_lnk_SetDefault_build )"
    fi
}

hb_lnk_main()
{
    (nm $1 -g -n --defined-only -C|sed -e '/ HB_FUN_/ ! d' -e 's/^[0-9a-fA-F]* T HB_FUN_\([A-Z0-9_]*\).*/\1/'|head -1|grep -v '^MAIN$')2>/dev/null
#    (nm $1 -n --defined-only|sed -e '/HB_FUN_/ ! d' -e 's/^[0-9a-fA-F]* [Tt] HB_FUN_//'|head -1|grep -v '^MAIN$')2>/dev/null
}

hb_cleanup()
{
    rm -f "${_TMP_FILE_}"
}

trap hb_cleanup EXIT &>/dev/null

case "${HB}" in
    *cc)
        hb_cc "${P[@]}"
        ;;
    *cmp)
        hb_cmp "${P[@]}"
        ;;
    *lnk)
        hb_link "${P[@]}" && \
        ( [ "${HB_STRIP}" != "yes" ] || strip "${FOUTE}" )
        ;;
    *mk)
        hb_cmp "${P[@]}" && \
        hb_link "${FOUTO}" && \
        ( [ "${HB_STRIP}" != "yes" ] || strip "${FOUTE}" ) && \
        rm -f "${FOUTO}"
        ;;
esac
