#!/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="dos"
export HB_COMPILER="djgpp"
[ -z "${HB_BIN_INSTALL}" ] && export HB_BIN_INSTALL="e:/compiler/xhbdj/bin"
[ -z "${HB_INC_INSTALL}" ] && export HB_INC_INSTALL="e:/compiler/xhbdj/include"
[ -z "${HB_LIB_INSTALL}" ] && export HB_LIB_INSTALL="e:/compiler/xhbdj/lib"

# 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 (default)
    -fullstatic         # link with all static libs
    -shared             # link with shared libs
    -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)
    -hwgui              # link with HWGUI library (GTK+ interface)
    -l<libname>         # link with <libname> library
    -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 gharbour harbour-link; do
            if [ "${HB_ARCHITECTURE}" = "dos" ]; then
                cp -f "${NAME}" "${n}"
            else
                ln -sf "${NAME}" "${n}"
            fi
        done
        )
    fi
    exit
fi

## default parameters
HB_STATIC="yes"
HB_MT=""
HB_GT="dos"
HB_MG="yes"

HB_GPM_MOUSE="no"

HB_GT_REQ=""
HB_FM_REQ=""
HB_STRIP="yes"
HB_MAIN_FUNC=""
HB_XBGTK=""
HB_HWGUI=""
HB_USRLIBS=""
HB_GENC=""
[ -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%.*}"
            elif [ -n "${d}" ]; then
                FILEOUT="${d}"; p="-o${d%.*}"
            fi ;;
        -static)     HB_STATIC="yes" ;;
        -fullstatic) HB_STATIC="full" ;;
        -shared)     HB_STATIC="no" ;;
        -xbgtk)      HB_XBGTK="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[a-zA-z]*) HB_USRLIBS="${HB_USRLIBS} ${v}" ;;
        -main=*)     HB_MAIN_FUNC="${v#*=}" ;;
        -gc|-gc[0-9]) HB_GENC="yes"; 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"
# 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}"
if [ "${HB_MG}" != "yes" ]; then
    if [ "${HB_STATIC}" = "yes" ] || [ "${HB_STATIC}" = "full" ]; then
        HB_GT_STAT=`echo ${HB_GT_REQ}|tr '[A-Z]' '[a-z]'`
    fi
    HB_GT_REQ=""
else
    HB_GT_REQ=`echo ${HB_GT_REQ}|tr '[a-z]' '[A-Z]'`
fi
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}"
LINK_OPT=""
CC_OPT=""

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="${SYSTEM_LIBS} -lslang"
    [ "${HB_GPM_MOUSE}" = "yes" ] && HB_GPM_LIB="gpm"
fi
if [ -f "${HB_LIB_INSTALL}/libgtcrs.a" ]; then
    SYSTEM_LIBS="${SYSTEM_LIBS} -lncurses"
    [ "${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="${SYSTEM_LIBS} -L/usr/X11R6/lib -lX11"
    fi
fi
[ -n "${HB_GPM_LIB}" ] && SYSTEM_LIBS="${SYSTEM_LIBS} -l${HB_GPM_LIB}"

if [ "${HB_STATIC}" = "full" ]; then
    SYSTEM_LIBS="${SYSTEM_LIBS} -ldl"
    if [ "${HB_ARCHITECTURE}" = "linux" ]; then
       SYSTEM_LIBS="${SYSTEM_LIBS} -lpthread"
    fi
    LINK_OPT="${LINK_OPT} -static"
    HB_STATIC="yes"
fi
if [ "${HB_XBGTK}" = "yes" ] || [ "${HB_HWGUI}" = "yes" ]; then
    SYSTEM_LIBS="${SYSTEM_LIBS} `pkg-config --libs gtk+-2.0`"
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 dbfntx hsx hbsix  macro common lang codepage gtnul gtcrs gtsln gtxvt gtxwc gtalleg gtcgi gtstd gtpca gtwin gtwvt gtdos gtos2 tip ct hbodbc debug profiler nf rddads"
else
    l="xharbour"
    if [ "${HB_ARCHITECTURE}" = "darwin" ]; then
        pref="lib"
        ext=".dylib"
        LINK_OPT="-bind_at_load -multiply_defined suppress"
    elif [ "${HB_ARCHITECTURE}" = "w32" ]; then
        pref=""
        ext=".dll"
        HB_LNK_ATTR="__attribute__ ((dllimport))"
    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 nf rddads"
fi
for l in ${libs}
do
    if [ "${HB_MG}" = "yes" ] || [ "${l#gt}" = "${l}" ] || [ "${l}" = "gt${HB_GT_STAT}" ]; then
        [ "${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
    fi
done
if [ "${HB_XBGTK}" = "yes" ]; then
    HARBOUR_LIBS="${HARBOUR_LIBS} -lxbgtk"
fi
if [ "${HB_HWGUI}" = "yes" ]; then
    HARBOUR_LIBS="${HARBOUR_LIBS} -lhwgui -lprocmisc -lhbxml"
fi
if [ "${HB_ARCHITECTURE}" = "darwin" ] || [ "${HB_ARCHITECTURE}" = "sunos" ]; then
    HARBOUR_LIBS="${HARBOUR_LIBS} ${HARBOUR_LIBS}"
else
    HARBOUR_LIBS="-Wl,--start-group ${HARBOUR_LIBS} -Wl,--end-group"
fi
l="fmstat"
[ "${HB_MT}" = "MT" ] && [ -f "${HB_LIB_INSTALL}/lib${l}mt.a" ] && l="${l}mt"
if [ -f "${HB_LIB_INSTALL}/lib${l}.a" ]; 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="-no-cpp-precomp -Wno-long-double"
elif [ "${HB_ARCHITECTURE}" = "sunos" ]; then
    HB_STRIP="no"
elif [ "${HB_ARCHITECTURE}" = "w32" ]; then
    CC_OPT=""
    HB_OPT=""
fi

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

hb_cc()
{
    ${HB_CC} "$@" ${CC_OPT} ${GCC_PATHS}
}

hb_cmp()
{
    harbour "$@" ${HB_OPT} ${HB_PATHS} && [ -f "${FOUTC}" ] && \
    hb_cc -c "${FOUTC}" -o "${FOUTO}" && \
    ( [ "${HB_GENC}" = "yes" ] || 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_} && \
        hb_cc "$@" "${_TMP_FILE_}" ${LINK_OPT} ${GCC_PATHS} ${HARBOUR_LIBS} ${HB_USRLIBS} ${SYSTEM_LIBS} -o "${FOUTE}"
    else
        hb_cc "$@" ${LINK_OPT} ${GCC_PATHS} ${HARBOUR_LIBS} ${HB_USRLIBS} ${SYSTEM_LIBS} -o "${FOUTE}"
    fi
}

hb_lnk_request()
{
    echo "#include \"hbapi.h\""
    if [ -n "${HB_LNK_REQ}" ]; then
        for fn in ${HB_LNK_REQ}; do
            echo "extern HB_FUNC( ${fn} );"
        done
        echo "void hb_lnk_ForceLink_build( void )"
        echo "{"
        for fn in ${HB_LNK_REQ}; do
            echo "   HB_FUNCNAME( ${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|sed -e '/HB_FUN_/ ! d' -e 's/^[0-9a-fA-F]* T HB_FUN_//'|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

## get basename
HB="${0##*/}"

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