#!/bin/sh
#
# toolchain detection
#

C_COMPILERS="cc gcc clang suncc"
CPP_COMPILERS="CC g++ clang++ sunCC"
unset CC_ARG_CHECKED
unset TOOLCHAIN_DETECTION_ERROR
unset TOOLCHAIN_NAME

check_c_compiler()
{
	cat > "$TEMP_DIR/test.c" << __EOF__
/* test file */
#include <stdio.h>
int main(int argc, char **argv) {
#if defined(__clang__)
	printf("clang\n");
#elif defined(__GNUC__)
	printf("gcc\n");
#elif defined(__sun)
	printf("suncc\n");
#else
	printf("unknown\n");
#endif
	return 0;
}
__EOF__
	rm -f "$TEMP_DIR/checkcc"
	$1 -o "$TEMP_DIR/checkcc" $CFLAGS $LDFLAGS "$TEMP_DIR/test.c" 2> /dev/null
	
	if [ $? -ne 0 ]; then
		return 1
	fi
	return 0
}

check_cpp_compiler()
{
	cat > "$TEMP_DIR/test.cpp" << __EOF__
/* test file */
#include <iostream>
int main(int argc, char **argv) {
#if defined(__clang__)
	std::cout << "clang" << std::endl;
#elif defined(__GNUC__)
	std::cout << "gcc" << std::endl;
#elif defined(__sun)
	std::cout << "suncc" << std::endl;
#else
	std::cout << "unknown" << std::endl;
#endif
	return 0;
}
__EOF__
	rm -f "$TEMP_DIR/checkcc"
	$1 -o "$TEMP_DIR/checkcc" $CXXFLAGS $LDFLAGS "$TEMP_DIR/test.cpp" 2> /dev/null
	
	if [ $? -ne 0 ]; then
		return 1
	fi
	return 0
}

check_lib()
{
	if [ -z "$TOOLCHAIN_LD" ]; then
		return 1
	fi
	cat > "$TEMP_DIR/test.c" << __EOF__
/* libtest file */
int main(int argc, char **argv) {
	return 0;
}
__EOF__
	rm -f "$TEMP_DIR/checklib"
	$TOOLCHAIN_LD -o "$TEMP_DIR/checklib" $CFLAGS $LDFLAGS "-l$1" "$TEMP_DIR/test.c" 2> /dev/null

	if [ $? -ne 0 ]; then
		return 1
	fi
	return 0
}

printf "detect C compiler... "

for COMP in $C_COMPILERS
do
	check_c_compiler "$COMP"
	if [ $? -ne 0 ]; then
		if [ -n "$CC" ]; then
			if [ "$COMP" = "$CC" ]; then
				echo "$CC is not a working C compiler"
				TOOLCHAIN_DETECTION_ERROR="error"
				break
			fi
		fi
	else
		TOOLCHAIN_NAME=`$TEMP_DIR/checkcc`
		USE_TOOLCHAIN=$TOOLCHAIN_NAME
		if [ "$COMP" = "cc" ]; then
			# we have found a working compiler, but in case
			# the compiler is gcc or clang, we try to use
			# these commands and not 'cc'
			TOOLCHAIN_NAME=`$TEMP_DIR/checkcc`
			if [ "$TOOLCHAIN_NAME" = "gcc" ]; then
				check_c_compiler "gcc"
				if [ $? -eq 0 ]; then
					COMP=gcc
					USE_TOOLCHAIN="gcc"
				fi
			fi
			if [ "$TOOLCHAIN_NAME" = "clang" ]; then
				check_c_compiler "clang"
				if [ $? -eq 0 ]; then
					COMP=clang
					USE_TOOLCHAIN="clang"
				fi
			fi
		fi
		
		TOOLCHAIN_NAME=$USE_TOOLCHAIN
		TOOLCHAIN_CC=$COMP
		echo $COMP
		break
	fi
done
if [ -z "$TOOLCHAIN_CC" ]; then
	echo "not found"
fi

printf "detect C++ compiler... "

for COMP in $CPP_COMPILERS
do
	check_cpp_compiler "$COMP"
	if [ $? -ne 0 ]; then
		if [ -n "$CXX" ]; then
			if [ "$COMP" = "$CXX" ]; then
				echo "$CXX is not a working C++ compiler"
				TOOLCHAIN_DETECTION_ERROR="error"
				break
			fi
		fi
	else
		if [ $COMP = "CC" ]; then
			# we have found a working compiler, but in case
			# the compiler is gcc or clang, we try to use
			# these commands and not 'CC'
			TOOLCHAIN_NAME=`$TEMP_DIR/checkcc`
			USE_TOOLCHAIN=$TOOLCHAIN_NAME
			if [ "$TOOLCHAIN_NAME" = "gcc" ]; then
				check_cpp_compiler "g++"
				if [ $? -eq 0 ]; then
				   COMP=g++
				   USE_TOOLCHAIN="gcc"
				fi
			fi
			if [ "$TOOLCHAIN_NAME" = "clang" ]; then
				check_cpp_compiler "clang++"
				if [ $? -eq 0 ]; then
				   COMP=clang++
				   USE_TOOLCHAIN="clang"
				fi
			fi
		fi
		
		TOOLCHAIN_NAME=$USE_TOOLCHAIN
		TOOLCHAIN_CXX=$COMP
		echo $COMP
		break
	fi
done
if [ -z "$TOOLCHAIN_CXX" ]; then
	echo "not found"
fi

TOOLCHAIN_LD=$TOOLCHAIN_CC

if [ -z "$TOOLCHAIN_NAME" ]; then
	TOOLCHAIN_DETECTION_ERROR="error"
else
	cat >> "$TEMP_DIR/config.mk" << __EOF__
# toolchain
__EOF__
	echo "CC = ${TOOLCHAIN_CC}" >> "$TEMP_DIR/config.mk"
	if [ -n "$TOOLCHAIN_CXX" ]; then
		echo "CXX = ${TOOLCHAIN_CXX}" >> "$TEMP_DIR/config.mk"
	fi
	echo "LD = ${TOOLCHAIN_LD}" >> "$TEMP_DIR/config.mk"
	echo >> "$TEMP_DIR/config.mk"
	
	if [ -f "make/${TOOLCHAIN_NAME}.mk" ]; then
		cat "make/${TOOLCHAIN_NAME}.mk" >> "$TEMP_DIR/config.mk"
	else
		cat >> "$TEMP_DIR/config.mk" << __EOF__
CFLAGS =
LDFLAGS =

SHLIB_CFLAGS = -fPIC
SHLIB_LDFLAGS = -shared
__EOF__
	fi
fi
