make/toolchain.sh

Sun, 23 Nov 2025 13:15:19 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 23 Nov 2025 13:15:19 +0100
changeset 1508
dfc0ddd9571e
parent 1492
cc83ce484bf7
permissions
-rw-r--r--

optimize sorted insertion by using the infimum instead of the supremum

The reason is that the supremum returns the equal element with the smallest index, and we want the largest.
Therefore, we use the infimum, which already gives us the largest index when there are equal elements, and increase the index by one. The infimum is also guaranteed to exist in that case.

#!/bin/sh
#
# toolchain detection
#

TAIL="tail"
if isplatform "bsd" && notisplatform "openbsd"; then
  C_COMPILERS="clang gcc cc"
  CPP_COMPILERS="clang++ g++ CC"
elif isplatform "solaris"; then
  C_COMPILERS="cc suncc gcc clang"
  CPP_COMPILERS="CC sunCC g++ clang++"
  if [ -f /usr/xpg4/bin/tail ]; then
    TAIL=/usr/xpg4/bin/tail
  fi
else
  C_COMPILERS="gcc clang cc"
  CPP_COMPILERS="g++ clang++ c++"
fi
unset TOOLCHAIN
unset TOOLCHAIN_NAME
unset TOOLCHAIN_CC
unset TOOLCHAIN_CXX

check_c_compiler()
{
  if ! command -v "$1" >/dev/null 2>&1 ; then
    return 1
  fi
  cat > "$TEMP_DIR/test.c" << __EOF__
/* test file */
#include <stdio.h>
int main(void) {
#if defined(_MSC_VER)
  printf("toolchain:msc\n");
#elif defined(__clang__)
  printf("toolchain:clang gnuc\n");
#elif defined(__GNUC__)
  printf("toolchain:gcc gnuc\n");
#elif defined(__sun)
  printf("toolchain:suncc\n");
#else
  printf("toolchain:unknown\n");
#endif
  printf("wsize:%d\n", (int)sizeof(void*)*8);
#ifdef __STDC_VERSION__
  printf("stdcversion:%ld\n", (long int)__STDC_VERSION__);
#endif
  return 0;
}
__EOF__
  rm -f "$TEMP_DIR/checkcc"
  $1 -o "$TEMP_DIR/checkcc" $CFLAGS $LDFLAGS "$TEMP_DIR/test.c" 2> /dev/null
}

check_cpp_compiler()
{
  if ! command -v "$1" >/dev/null 2>&1 ; then
    return 1
  fi
  cat > "$TEMP_DIR/test.cpp" << __EOF__
/* test file */
#include <iostream>
int main(void) {
#if defined(_MSC_VER)
  std::cout << "toolchain:msc" << std::endl;
#elif defined(__clang__)
  std::cout << "toolchain:clang gnuc" << std::endl;
#elif defined(__GNUC__)
  std::cout << "toolchain:gcc gnuc" << std::endl;
#elif defined(__sun)
  std::cout << "toolchain:suncc" << std::endl;
#else
  std::cout << "toolchain:unknown" << std::endl;
#endif
  std::cout << "wsize:" << sizeof(void*)*8 << std::endl;
  return 0;
}
__EOF__
  rm -f "$TEMP_DIR/checkcc"
  $1 -o "$TEMP_DIR/checkcc" $CXXFLAGS $LDFLAGS "$TEMP_DIR/test.cpp" 2> /dev/null
}

parse_toolchain_properties()
{
  info_file="$1"
  TOOLCHAIN=`grep '^toolchain:' "$info_file" | $TAIL -c +11`
  TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
  TOOLCHAIN_WSIZE=`grep '^wsize:' "$info_file" | $TAIL -c +7`
}

detect_c_compiler()
{
  if [ -n "$TOOLCHAIN_CC" ]; then
    return 0
  fi
  printf "detect C compiler... "
  if [ -n "$CC" ]; then
    if check_c_compiler "$CC"; then
      TOOLCHAIN_CC=$CC
      "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
      parse_toolchain_properties "$TEMP_DIR/checkcc_out"
      TOOLCHAIN_CSTD=`grep '^stdcversion:' "$TEMP_DIR/checkcc_out" | $TAIL -c +13`
      echo "$CC"
      return 0
    else
      echo "$CC is not a working C compiler"
      return 1
    fi
  else
    for COMP in $C_COMPILERS
    do
      if check_c_compiler "$COMP"; then
        TOOLCHAIN_CC=$COMP
        "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
        parse_toolchain_properties "$TEMP_DIR/checkcc_out"
        TOOLCHAIN_CSTD=`grep '^stdcversion:' "$TEMP_DIR/checkcc_out" | $TAIL -c +13`
        echo "$COMP"
        return 0
      fi
    done
    echo "not found"
    return 1
  fi
}

detect_cpp_compiler()
{
  if [ -n "$TOOLCHAIN_CXX" ]; then
    return 0
  fi
  printf "detect C++ compiler... "

  if [ -n "$CXX" ]; then
    if check_cpp_compiler "$CXX"; then
      TOOLCHAIN_CXX=$CXX
      "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
      parse_toolchain_properties "$TEMP_DIR/checkcc_out"
      echo "$CXX"
      return 0
    else
      echo "$CXX is not a working C++ compiler"
      return 1
    fi
  else
    for COMP in $CPP_COMPILERS
    do
      if check_cpp_compiler "$COMP"; then
        TOOLCHAIN_CXX=$COMP
        "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
        parse_toolchain_properties "$TEMP_DIR/checkcc_out"
        echo "$COMP"
        return 0
      fi
    done
    echo "${TOOLCHAIN_CXX:-"not found"}"
    return 1
  fi
}

write_toolchain_defaults()
{
  echo "# toolchain" >> "$1"
  if [ -n "$TOOLCHAIN_CC" ]; then
    echo "CC = ${TOOLCHAIN_CC}" >> "$1"
  fi
  if [ -n "$TOOLCHAIN_CXX" ]; then
    echo "CXX = ${TOOLCHAIN_CXX}" >> "$1"
  fi
  echo >> "$1"
  if [ -f "make/${TOOLCHAIN_NAME}.mk" ]; then
    cat "make/${TOOLCHAIN_NAME}.mk" >> "$1"
  elif [ -f "make/cc.mk" ]; then
    cat "make/cc.mk" >> "$1"
  else
    echo "!!! WARNING !!! Default toolchain flags not found. Configuration might be incomplete."
  fi
}

mercurial