#!/bin/bash
#
#	bld -- Build archives, shared libraries and executables (aka mini libtool)
#
#	Copyright (c) Mbedthis LLC, 2003-2007. All Rights Reserved.
#
#	It is expected that bld is only invoked from the Mbedthis build systems. It
#	expects make.var and make.rules to have defined all the necessary compile 
#	and link flag environment variables.
#
#
###############################################################################
#
#	Must exit if anything goes wrong
#
set -e 

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

. ${BLD_TOP}/buildConfig.sh

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

usage() {
    cat <<!EOF
bld: usage: bld [options] objects ....
    Options:
    --c++                   Program includes C++ components
    --debug                 Not implemented
    --dry-run               Trace commands but do not execute
    --entry name            Shared library entry point
    --executable name       Name of executable to build
    --graphical             Create a windowed program instead of a console.
    --help                  Print usage information
    --library name          Name of library to link
    --libraryPath "paths"   Paths to search for the libraries
    --libs libraries        Extra libraries to link with. Use shared or static 
                            intelligently depending on --preferShared, 
                            --preferStatic and BLD_FEATURE_STATIC and 
                            BLD_FEATURE_SHARED. Will search libraries with lib
                            prefix and Static suffix.
    --omitstdlibs           Don't use standard libraries (UNIX only)
    --objects "objects..."  String containing objects to link
    --objectsDir path       Directory to find / store objects
    --quiet                 Run quietly without tracing actions to stdout
    --preferShared          Link with shared libraries by preference
    --preferStatic          Link with static libraries by preference
    --resources file        Resource file (menus and icons for Windows)
    --rpath path            Specify the executable run-time library search path
    --shared                Only make a shared library
    --soname                Create a shared library with soname (no version)
    --static                Only make a static library
    --syslibs libraries     Extra system libraries to link with
    --version               Print the bld version
    --versionSoname         Create a versioned shared library with soname
    --verbose               Verbose operation. Traces internal information.

    Environment variables used:
      BLD_TOP               Top of the source tree
      BLD_FEATURE_SHARED    Build shared libraries where relevant.
      BLD_FEATURE_STATIC    Build static libraries where relevant.

    Configuration files used:
        buildConfig.sh
!EOF
    exit 255
}

###############################################################################
#
#	Some shells don't have a standard getopts. Must supply our own.
#
#	Spec chars: ';' == no arg, ':' required arg, '.' optional arg
#

getoptex()
{
	let $# || return 1
	local optlist="${1#;}"
	let OPTIND || OPTIND=1
	[ $OPTIND -lt $# ] || return 1
	shift $OPTIND
	if [ "$1" != "-" -a "$1" != "${1#-}" ]
	then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ]
	then
		local o
		o="-${1#-$OPTOFS}"
		for opt in ${optlist#;}
		do
			OPTOPT="${opt%[;.:]}"
			unset OPTARG
			local opttype="${opt##*[^;:.]}"
			[ -z "$opttype" ] && opttype=";"
			if [ ${#OPTOPT} -gt 1 ]
			then # long-named option
				case $o in
				"--$OPTOPT")
					if [ "$opttype" != ":" ]; then return 0; fi
					OPTARG="$2"
					if [ "$OPTARG" != "${OPTARG#-}" ];
					then # error: must have an agrument
						let OPTERR && \
							echo "$0: error: $OPTOPT must have an argument" >&2
						OPTARG="$OPTOPT";
						OPTOPT="?"
						return 1;
					fi
					OPTIND=$[OPTIND+1] # skip option's argument
					return 0
				;;
				"--$OPTOPT="*)
					if [ "$opttype" = ";" ];
					then	# error: must not have arguments
						let OPTERR && \
						  echo "$0: error: $OPTOPT must not have arguments" >&2
						OPTARG="$OPTOPT"
						OPTOPT="?"
						return 1
					fi
					OPTARG=${o#"--$OPTOPT="}
					return 0
				;;
				esac
			else # short-named option
				case "$o" in
					"-$OPTOPT")
						unset OPTOFS
						[ "$opttype" != ":" ] && return 0
						OPTARG="$2"
						if [ -z "$OPTARG" ]
						then
							echo "$0: error: -$OPTOPT must have an argument" >&2
							OPTARG="$OPTOPT"
							OPTOPT="?"
							return 1
						fi
						OPTIND=$[OPTIND+1] # skip option's argument
						return 0
					;;
					"-$OPTOPT"*)
						if [ $opttype = ";" ]
						then 
							# option with no argument is in a chain of options
							# move to the next option in the chain
							# the chain still has other options
							OPTOFS="$OPTOFS?" 
							OPTIND=$[OPTIND-1] 
							return 0
						else
							unset OPTOFS
							OPTARG="${o#-$OPTOPT}"
							return 0
						fi
					;;
				esac
			fi
		done
		echo "$0: error: invalid option: $o"
	fi; fi
	OPTOPT="?"
	unset OPTARG
	return 1
}

###############################################################################
#
#	Search for library in the specified search locations.
#

searchLib()
{
	local syslib path libName extraSysLib

	prefix="$1"
	name="$2"
	suffix="$3"

	libName="${prefix}${name}${suffix}"

	[ "$VERBOSE" -gt 0 ] &&
		echo -e "\nbld: searchLib for ${libName}" >/dev/tty

	#	TODO - should be BLD_CPU
	if [ "$BLD_CPU" = "x86_64" -a -x /usr/lib64 ] ; then
		syslib=/usr/lib64
	else
		syslib=/usr/lib
	fi

	#	TODO - put back in build/os/config.MACOSX
	if [ "$BLD_OS" = MACOSX ] ; then
		extraSysLib=/usr/local/lib
	fi

	for path in ${LIBRARY_PATHS} "${BLD_LIB_DIR}" "${BLD_LIB_PREFIX}" "$syslib" "$extraSysLib"
	do
		[ "$path" = "" ] && continue

		[ "$VERBOSE" -gt 0 ] &&
			echo "bld: TESTING ${path}/${libName}" >/dev/tty

		if [ -f "${path}/${libName}" ] 
		then
			[ "$VERBOSE" -gt 0 ] &&
				echo -e "bld: FOUND ${path}/${libName}\n" >/dev/tty

			#	TODO - do this for BLD_UNIX
			if [ "$OS" = "LINUX" -a "$path" = "${BLD_LIB_PREFIX}" ]
			then
				echo "-l${name}"
				return
			fi

			#
			#	To allow LD_LIBRARY_PATH to work, we must use -l${name} form
			#	if possible. We do this if the library is prefixed with "lib"
			#	and is a shared library with a plain ".so" extension.
			#
			# 	TODO - this should be BLD_UNIX
			if [ "${prefix}" = "lib" -a "${suffix}" = "${BLD_SHLIB}" -a "$BLD_UNIX" = 1 ]
			then
				echo "-l${name}"
			else
				echo "${path}/${libName}"
			fi
			return
		fi
	done
	echo ""
}

###############################################################################
#
#	Find a library. Look in the library paths with a "lib" prefix first and
#	optionally with a Static suffix
#

findLib()
{
	local path libName static suffixes

	libName="$1"

	#
	#	Example Search order (for Linux):
	#		nameStatic.a 	(if nameStatic explicitly specified)
	#		name.so			(if --preferShared and shared enabled)
	#		nameStatic.a 	(if --preferStatic and static enabled)
	#		name.so			
	#		name.a			
	#
	suffixes=

	doneStatic=0
	doneShared=0

	if [ "$libName" != "${libName/Static/}" ]
	then
		suffixes="$suffixes Static${BLD_ARCH}"
		doneStatic=1
	fi

	if [ $PREFER_SHARED = 1 -a $BLD_FEATURE_SHARED = 1 ]
	then
		suffixes="$suffixes ${BLD_SHLIB}"
		doneShared=1
	fi

	if [ $PREFER_STATIC = 1 -a $BLD_FEATURE_STATIC = 1 -a $doneStatic != 1 ]
	then
		suffixes="$suffixes Static${BLD_ARCH}"
		doneStatic=1
	fi

	if [ $doneShared != 1 ]
	then
		suffixes="$suffixes ${BLD_SHLIB}"
		doneShared=1
	fi

	suffixes="$suffixes ${BLD_ARCH}"

	libName=`echo ${libName} | sed 's/Static//'`
	libName="${libName%$BLD_ARCH}"
	libName="${libName%$BLD_SHLIB}"

	[ "$VERBOSE" -gt 0 ] &&
		echo -e "\nbld: findLib: search for $libName using suffixes \"$suffixes\"" >/dev/tty

	for prefix in lib ""
	do
		for suffix in `echo $suffixes`
		do
			newName=`searchLib ${prefix} ${libName} ${suffix}`
			if [ "$newName" != "" ]
			then
				echo "$newName"
				return
			fi
		done
	done

	echo -e "\nWarning: bld could not find library $libName. Build may not complete." >/dev/tty

	if [ "${BLD_SHLIB}" -a "$BLD_UNIX" = 1 ]
	then
		echo "-l${name}"
	else
		echo "${libName}.lib"
	fi
}

###############################################################################
#
#	For some reason, link commands can complete and the executable is not yet visible
#	on windows.
#
waitFor() {
	local timeout file

	file=$1
	timeout=$2

	while [ ! -x $file -a $timeout -gt 0 ] ; do
		[ $VERBOSE -gt 0 ] && echo "File $file not yet present, waiting ..."
		sleep 1
		timeout=$(($timeout - 1))
	done
}


###############################################################################
#
#	Main
#

echo -en "\n    # bld "
for arg in "$@"
do
	echo -n "\"$arg\" "
done
echo

ARCHIVE=
DEBUG=
DO=
ENTRY=
EXECUTABLE=
FILE_LIST=
GRAPHICAL=
LIBRARY=
LIBRARY_PATHS=
LIBS=
MAKE_SHARED=0
MAKE_STATIC=0
OMITSTDLIBS=0
RESOURCES=
OBJECTS=
PREFER_SHARED=0
PREFER_STATIC=0
RPATH_LIST=
SHARED_LIBRARY=
SONAME=0
SYSLIBS=
VERSION=1.0
VERSION_SONAME=0
VERBOSE=0

#
#	Reset default directory locations. We require explicit --objectsDir
#
BLD_OBJ_DIR=.

while getoptex "\
	c++ \
	debug \
	dry-run \
	entry: \
	executable: \
	graphical \
	help \
	libs: \
	library: \
	libraryPath: \
	omitstdlibs \
	objects: \
	objectsDir: \
	objectList: \
	preferShared \
	preferStatic \
	quiet \
	resources: \
	rpath: \
	shared \
	soname \
	static \
	syslibs: \
	version
	versionSoname
	verbose" \
"$@"
do
	case "$OPTOPT" in 
	c++)
		HAS_CPLUSPLUS=1
		;;
	debug)
		DEBUG=1
		echo "Not yet implemented"
		;;
	dry-run)
		DO=:
		;;
	entry)
		ENTRY="$OPTARG"
		;;
	executable)
		EXECUTABLE="$OPTARG"
		;;
	graphical)
		GRAPHICAL=1
		;;
	help)
		usage
		;;
	library)
		dir="${OPTARG%${OPTARG##*/}}"
		# "${dir:=./}" != "/" && dir="${dir%?}"
		: ${dir:=./}
		basename=${OPTARG##*/}
		noExtension=${basename%\.*}
		noExtension=${noExtension%Static}
		LIBRARY="${dir}${noExtension}"
		;;
	libraryPath)
		LIBRARY_PATHS="$LIBRARY_PATHS $OPTARG"
		;;
	libs)
		LIBS="$LIBS $OPTARG"
		;;
	omitstdlibs)
		OMITSTDLIBS=1
		;;
	objects)
		OBJECTS="$OBJECTS ${OPTARG}"
		;;
	objectsDir)
		#
		#	Objects may use this variable in their names
		#
		BLD_OBJ_DIR="${OPTARG}"
		;;
	objectList)
		FILE_LIST="$FILE_LIST $OPTARG"
		;;
	preferShared)
		#	MOB -- doesn't really do much
		PREFER_SHARED=1
		;;
	preferStatic)
		PREFER_STATIC=1
		;;
	quiet)
		;;
	resources)
		RESOURCES="$OPTARG"
		;;
	rpath)
		RPATH_LIST="$RPATH_LIST $OPTARG"
		;;
	shared)
		MAKE_SHARED=1
		;;
	soname)
		SONAME=1
		;;
	static)
		MAKE_STATIC=1
		;;
	syslibs)
		SYSLIBS="$SYSLIBS $OPTARG"
		;;
	version)
		echo $VERSION
		exit 0
		;;
	versionSoname)
		SONAME=1
		VERSION_SONAME=1
		;;
	verbose)
		VERBOSE=1
		;;
	*)	echo "bld: bad option: $OPTOPT"
		exit 2
		;;
	esac
done

shift $[OPTIND-1]

OS=${BLD_OS}

if [ $BLD_FEATURE_SHARED = 0 -a $PREFER_SHARED = 1 ]
then
	PREFER_STATIC=1
fi

#
#	If neither --static or --shared is specified, build both or either. 
#	Whatever compiles with the configure setup.
#
if [ "$LIBRARY" -a $MAKE_STATIC = 0 -a $MAKE_SHARED = 0 ]
then
	if [ $BLD_FEATURE_SHARED = 1 ]
	then
		MAKE_SHARED=1
	fi
	if [ $BLD_FEATURE_STATIC = 1 ]
	then
		MAKE_STATIC=1
	fi
fi

if [ "${FILE_LIST}" ]
then
	for f in ${FILE_LIST}
	do
		OBJECTS="$OBJECTS `cat ${f}`"
	done
fi

#
#	Expand make variables in the objects
#
OBJECTS=`eval echo ${OBJECTS} $*`

#
#	Prepare for action
#
if [ "$OS" = "WIN" -o "$OS" = "BREW" -o "$OS" = "BREWSIM" ]
then
	paths=
	for p in ${LIBRARY_PATHS} 
	do
		paths="${paths} -libpath:${p}"
	done
	LINK_LIBRARY_PATHS=${paths}

	LIB_LIST=
	
	for l in ${LIBS} 
	do
		libName=`findLib $l` 
		LIB_LIST="${LIB_LIST} ${libName}"
	done

	for l in ${SYSLIBS} 
	do
		LIB_LIST="${LIB_LIST} ${l}"
	done

	if [ "$LIBRARY" != "" ]
	then
		if [ $MAKE_SHARED = 1 -a "$ENTRY" = "" ]
		then
			ENTRY="_DllMainCRTStartup@12"
		fi
	fi

	if [ "$EXECUTABLE" ]
	then
		if [ "$GRAPHICAL" ]
		then 
			ENTRY=WinMainCRTStartup
			SUBSYSTEM="WINDOWS"
		else 
			ENTRY=mainCRTStartup
			SUBSYSTEM="CONSOLE"
		fi
	fi

else
	#
	#	Unix / Linux / MacOS / FreeBSD
	#
	paths=
	for p in ${LIBRARY_PATHS} 
	do
		paths="${paths} -L${p}"
	done
	LINK_LIBRARY_PATHS=${paths}

	#
	#	On VxWorks, we ignore libraries except if build an executable.
	#	We must also use an absolute path to the library
	#
	LIB_LIST=
	#	TODO - does this matter for vxworks
	if [ "$OS" != "VXWORKS" -o "$EXECUTABLE" ]
	then
		for l in ${LIBS}
		do
			libName=`findLib $l` 
			LIB_LIST="${LIB_LIST} $libName"
		done
	fi

	if [ "$RPATH_LIST" != "" ]
	then
		for path in $RPATH_LIST
		do
			if [ "$OS" = "SOLARIS" ]
			then
				RPATH="$RPATH -R$path"
			#	TODO - what about FreeBSD and MACOSX
			elif [ "$OS" = "LINUX" ]
			then
				RPATH="$RPATH -Wl,--enable-new-dtags -Wl,-rpath=$path"
			else
				RPATH=""
			fi
		done
	fi
fi

#
#	If on UNIX/Linux, then support the --omitstdlibs switch
#
#	TODO - should be BLD_UNIX
if [ "$OMITSTDLIBS" = "0" -o "$BLD_UNIX" != 1 ]
then
	if [ "$BLD_FEATURE_STATIC_LIBC" = "1" ]
	then
		STND_LIBS=$_STATIC_LIBS
	else
		STND_LIBS=$_SHARED_LIBS
	fi
	if [ "$HAS_CPLUSPLUS" = "1" ] ; then
		STND_LIBS="$STND_LIBS $_CXX_LIBS"
	fi
fi

if [ "$HAS_CPLUSPLUS" = "1" ] ; then
	LINKER=${BLD_LDXX}
else
	LINKER=${BLD_LD}
fi

#
#	Now we do the actual work
#
if [ "$OS" = "WIN" -o "$OS" = "BREW" -o "$OS" = "BREWSIM" ]
then
	if [ "$LIBRARY" != "" ]
	then
		if [ $MAKE_STATIC = 1 -a $BLD_FEATURE_STATIC = 1 ]
		then
			ARCHIVE=${LIBRARY}Static${BLD_ARCH}
			echo \"${BLD_AR}\" -nologo -out:${ARCHIVE} ${OBJECTS}
			${DO} "${BLD_AR}" -nologo "-out:${ARCHIVE}" ${OBJECTS}
		fi

		if [ $MAKE_SHARED = 1 -a $BLD_FEATURE_SHARED = 1 ]
		then
			DEF=${LIBRARY}.def
			SHARED_LIBRARY=${LIBRARY}.dll
			echo dumpext -o ${DEF} `basename ${SHARED_LIBRARY}` ${OBJECTS}
			dumpext -o ${DEF} `basename ${SHARED_LIBRARY}` ${OBJECTS}
			echo

			if [ "$OS" = "WIN" ]
			then
				ENTRY_SW="-entry:${ENTRY}"
				DEF_SW="-def:${DEF}"
			else
				ENTRY_SW=""
				DEF_SW=""
			fi
			#
			#	Test if using VS 2005 linker with manifests
			#
			set +e
			echo \"${LINKER}\" -out:${SHARED_LIBRARY} ${_LD_SHARED} ${_LD_OPT} \
				${ENTRY_SW} ${DEF_SW} ${MAKE_LDFLAGS} ${BLD_LDFLAGS} \
				${LINK_SWITCHES} \
				${_LDFLAGS} ${LINK_LIBRARY_PATHS} -libpath:${_LDPATH} \
				${OBJECTS} ${LIB_LIST} ${STND_LIBS}
			${DO} "${LINKER}" "-out:${SHARED_LIBRARY}" ${_LD_SHARED} ${_LD_OPT} \
				${ENTRY_SW} ${DEF_SW} ${MAKE_LDFLAGS} ${BLD_LDFLAGS} \
				${LINK_SWITCHES} \
				${_LDFLAGS} ${LINK_LIBRARY_PATHS} "-libpath:${_LDPATH}" \
				${OBJECTS} ${LIB_LIST} ${STND_LIBS} >/tmp/link$$.tmp
			status=$?
			if [ $status = 0 ]
			then
				cat /tmp/link$$.tmp | grep -v "Creating library"
			else
				cat /tmp/link$$.tmp 
			fi
			rm -f /tmp/link$$.tmp 
			set -e

			if [ "${BLD_MT}" != "" -a -f ${SHARED_LIBRARY}.manifest ] ; then
				echo \"${BLD_MT}\" /manifest ${SHARED_LIBRARY}.manifest \
					"/outputresource:${SHARED_LIBRARY};#2"
				"${BLD_MT}" /nologo /manifest ${SHARED_LIBRARY}.manifest \
					"/outputresource:${SHARED_LIBRARY};#2"
				rm -f ${SHARED_LIBRARY}.manifest
			fi
		fi
	fi

	if [ "$EXECUTABLE" ]
	then
		if [ "$RESOURCES" ]
		then
			RES_OBJ=`echo $RESOURCES | sed s/\.rc//`.res
			echo "    rc -fo $RES_OBJ $RESOURCES"
			rc -fo $RES_OBJ $RESOURCES
		else 
			RES_OBJ=
		fi

		rm -f ${EXECUTABLE%${BLD_EXE}}.pdb

		#
		#	Test if using VS 2005 linker with manifests
		#
		echo \"${LINKER}\" -out:${EXECUTABLE} ${_LD_OPT} -entry:${ENTRY} \
			-subsystem:${SUBSYSTEM} ${RES_OBJ} ${MAKE_LDFLAGS} ${BLD_LDFLAGS} \
			${_LDFLAGS} ${LINK_LIBRARY_PATHS} -libpath:${_LDPATH} ${OBJECTS} \
			${LIB_LIST} ${STND_LIBS}

		${DO} "${LINKER}" "-out:${EXECUTABLE}" ${_LD_OPT} -entry:${ENTRY} \
			-subsystem:${SUBSYSTEM} ${RES_OBJ} ${MAKE_LDFLAGS} ${BLD_LDFLAGS} \
			${_LDFLAGS} ${LINK_LIBRARY_PATHS} "-libpath:${_LDPATH}" ${OBJECTS} \
			${LIB_LIST} ${STND_LIBS}

		if [ "${BLD_MT}" != "" -a -f ${EXECUTABLE}.manifest ] ; then
			echo \"${BLD_MT}\" /manifest ${EXECUTABLE}.manifest \
				"/outputresource:${EXECUTABLE};#1"
			"${BLD_MT}" /nologo /manifest ${EXECUTABLE}.manifest \
				"/outputresource:${EXECUTABLE};#1"
			rm -f ${EXECUTABLE}.manifest
		fi
	fi

else
	#
	#	Unix (Linux, Solaris, VxWorks, MacOSX)
	#
	if [ "$LIBRARY" ]
	then
		if [ $MAKE_STATIC = 1 ]
		then
			ARCHIVE=${LIBRARY}Static${BLD_ARCH}
			rm -f ${ARCHIVE}
			echo \"${BLD_AR}\" cr ${ARCHIVE} ${OBJECTS}
			${DO} "${BLD_AR}" cr ${ARCHIVE} ${OBJECTS}
			if [ "${BLD_RANLIB}" != "" ]
			then
				echo \"${BLD_RANLIB}\" ${ARCHIVE}
				${DO} "${BLD_RANLIB}" ${ARCHIVE}
			fi
		fi

		if [ $MAKE_SHARED = 1 ]
		then
			#	TODO should test if PIOBJ is defined or != BLD_OBJ and handle if so.
			if [ $OS != "VXWORKS" -a $OS != "CYGWIN" ]
			then
				#	TODO - should be BLD_PIOBJ
				LOBJS=`echo ${OBJECTS} | sed "s/\.o/${BLD_PIOBJ}/g"`
			else
				LOBJS=${OBJECTS}
			fi

			if [ $SONAME = 1 ]
			then
				if [ $OS = "LINUX" -o $OS = "SOLARIS" ] ; then
					if [ $VERSION_SONAME = 1 ] ; then
						SHARED_LIBRARY=${LIBRARY}${BLD_SHOBJ}.${BLD_VERSION}
						SONAME_LIBRARY=${LIBRARY}${BLD_SHOBJ}.${BLD_VERSION%????}
					else
						SHARED_LIBRARY=${LIBRARY}${BLD_SHOBJ}
						SONAME_LIBRARY=${LIBRARY}${BLD_SHOBJ}
					fi
					if [ "$OS" = "SOLARIS" ] ; then
						SONAME_SWITCH="-h=`basename $SONAME_LIBRARY`"
					else
						SONAME_SWITCH="-Wl,-soname=`basename $SONAME_LIBRARY`"
					fi

				elif [ $OS = "MACOSX" ] ; then
					SHARED_LIBRARY=${LIBRARY}${BLD_SHOBJ}
					if [ "$VERSION_SONAME" = 1 ]
					then
						SHARED_LIBRARY=${LIBRARY}.${BLD_VERSION}.dylib
						SONAME_LIBRARY=${LIBRARY}.${BLD_VERSION%????}.dylib
					else
						SHARED_LIBRARY=${LIBRARY}.dylib
						SONAME_LIBRARY=${LIBRARY}.dylib
					fi
					SONAME_SWITCH=""
					# VER=${BLD_VERSION%??}
					# TODO add --current_version=${VER} -compatibility_version=${VER}

				else 
					SHARED_LIBRARY=${LIBRARY}${BLD_SHOBJ}
					SONAME_LIBRARY=${LIBRARY}${BLD_SHOBJ}
				fi

			else
				#	TODO - should be BLD_SHOBJ
				SHARED_LIBRARY=${LIBRARY}${BLD_SHOBJ}
				SONAME_SWITCH=""
			fi
			echo \"${LINKER}\" -o ${SHARED_LIBRARY} ${SONAME_SWITCH} \
				${_LD_SHARED} ${_LD_OPT} ${MAKE_LDFLAGS} ${BLD_CFLAGS} ${_LDFLAGS} \
				${LINK_LIBRARY_PATHS} ${_LDPATH} ${RPATH} ${LOBJS} \
				${LIB_LIST}
			eval ${DO} "${LINKER}" -o ${SHARED_LIBRARY} ${SONAME_SWITCH} \
				${_LD_SHARED} ${_LD_OPT} ${MAKE_LDFLAGS} ${BLD_CFLAGS} ${_LDFLAGS} \
				${LINK_LIBRARY_PATHS} ${_LDPATH} ${RPATH} ${LOBJS} ${LIB_LIST}

			#	TODO - would be good to parameterize this somhow
 			if [ $OS != VXWORKS -a $OS != CYGWIN -a $SONAME = 1 -a $VERSION_SONAME = 1 ]
			then
				rm -f ${SONAME_LIBRARY}
				#	TODO - should be BLD_SHOBJ
				LINK_LIBRARY=${LIBRARY}${BLD_SHOBJ}
				rm -f ${LINK_LIBRARY}
				set +e
				ln -s `basename ${SHARED_LIBRARY}` ${SONAME_LIBRARY} 2>/dev/null
				if [ $? != 0 ]
				then
					cp ${SHARED_LIBRARY} ${SONAME_LIBRARY}
				fi
				ln -s `basename ${SONAME_LIBRARY}` ${LINK_LIBRARY} 2>/dev/null
				if [ $? != 0 ]
				then
					cp ${SONAME_LIBRARY} ${LINK_LIBRARY}
				fi
				set -e
 			fi
		fi
	fi

	if [ "$EXECUTABLE" ]
	then
		if [ "$BLD_FEATURE_STATIC_LIBC" = "1" ]
		then
			echo \"${LINKER}\" -o ${EXECUTABLE} ${_WARNING} ${_LD_OPT} \
				${MAKE_LDFLAGS} ${BLD_LDFLAGS} ${_LDFLAGS} \
				${LINK_LIBRARY_PATHS} ${_LDPATH} ${RPATH} ${OBJECTS} \
				${LIB_LIST} ${STND_LIBS}
			eval ${DO} \"${LINKER}\" -o ${EXECUTABLE} ${_WARNING} ${_LD_OPT} \
				${MAKE_LDFLAGS} ${BLD_LDFLAGS} ${_LDFLAGS} \
				${LINK_LIBRARY_PATHS} ${_LDPATH} ${RPATH} ${OBJECTS} \
				${LIB_LIST} ${STND_LIBS}
		else
			echo \"${LINKER}\" -o ${EXECUTABLE} ${_WARNING} ${_LD_OPT} \
				${MAKE_LDFLAGS} ${BLD_LDFLAGS} ${_LDFLAGS} \
				${LINK_LIBRARY_PATHS} ${_LDPATH} ${RPATH} ${OBJECTS} \
				${LIB_LIST} ${STND_LIBS}
			eval ${DO} \"${LINKER}\" -o ${EXECUTABLE} ${_WARNING} ${_LD_OPT} \
				${MAKE_LDFLAGS} ${BLD_LDFLAGS} ${_LDFLAGS} \
				${LINK_LIBRARY_PATHS} ${_LDPATH} ${RPATH} ${OBJECTS} \
				${LIB_LIST} ${STND_LIBS}
		fi
		# waitFor $EXECUTABLE 10
	fi

	#
	#	Need to "munch" the C++ programs and libraries to ensure 
	#	constructors and desructors are called
	#
 	if [ $OS = VXWORKS ] ; then

		if [ "$EXECUTABLE" ] ; then
			ORIG=${EXECUTABLE}
		fi

		if [ "$SHARED_LIBRARY" ] ; then
			ORIG=${SHARED_LIBRARY}
		fi

		if [ "$ORIG" ] ; then

			#	TODO - should be BLD_DIST_VER
			if [ "${BLD_DIST_VER}" = "5.4" ] ; then
				#
				#	VxWorks 5.4 uses wtxtcl instead of tclsh 
				#
				BLD_TCLSH=${BLD_TCLSH/tclsh/wtxtcl}
			fi
			type -p cygpath >/dev/null 2>&1
			if [ $? = 0 ] ; then
				#
				#	Must be a dos path
				#
				BLD_MUNCH=`cygpath -m ${BLD_MUNCH}`
			fi

			echo ${BLD_NM} ${ORIG} \| \
				${BLD_TCLSH} ${BLD_MUNCH} -asm ${BLD_BUILD_CPU_VX} \> ctdt.c
			${BLD_NM} ${ORIG} | ${BLD_TCLSH} ${BLD_MUNCH} -asm ${BLD_BUILD_CPU_VX} > ctdt.c

			echo ${LINKER} -c ${_CC_OPT} ${_WARNING} ${MAKE_CFLAGS} \
				${_CFLAGS} ${BLD_CFLAGS} ${MAKE_IFLAGS} ${BLD_IFLAGS} \
				${_IFLAGS} ctdt.c -o ctdt.o
			${LINKER} -c ${_CC_OPT} ${_WARNING} ${MAKE_CFLAGS} \
				${_CFLAGS} ${BLD_CFLAGS} ${MAKE_IFLAGS} ${BLD_IFLAGS} \
				${_IFLAGS} ctdt.c -o ctdt.o

			echo mv ${ORIG} ${ORIG}.orig
			mv ${ORIG} ${ORIG}.orig

	#		if [ "$BLD_BUILD_CPU_VX" = "simpc" ]
	#		then
	#			FLAGS="--subsystem=windows -r -Wl,-X -Wl,--force-stabs-reloc"
	#		fi
			echo ${DO} \"${LINKER}\" -o ${ORIG} \
				${SONAME_SWITCH} ${_LD_SHARED} ${_LD_OPT} ${MAKE_LDFLAGS} \
				${BLD_LDFLAGS} ${_LDFLAGS} ${LINK_LIBRARY_PATHS} ${_LDPATH} \
				${RPATH} ctdt.o ${ORIG}.orig
			eval ${DO} "${LINKER}" -o ${ORIG} ${SONAME_SWITCH} \
				${_LD_SHARED} ${_LD_OPT} ${MAKE_LDFLAGS} ${BLD_LDFLAGS} \
				${_LDFLAGS} ${LINK_LIBRARY_PATHS} ${_LDPATH} ${RPATH} \
				ctdt.o ${ORIG}.orig
			# waitFor $ORIG 10
			rm -f ${ORIG}.orig ctdt.* 

		fi
	fi
fi

exit 0


function basename()
{
	local name="${1##*/}"
	echo "${name%$2}"
}

