make/toolchain.sh

Fri, 23 May 2025 12:44:24 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 23 May 2025 12:44:24 +0200
changeset 1327
ed75dc1db503
parent 1310
ca52ea73a4ca
child 1330
caa66055b025
permissions
-rw-r--r--

make test-compile depend on both static and shared

the shared lib is not needed for the tests,
but when run with coverage, gcov will be confused
when outdated line information is available from
a previous shared build

#!/bin/sh
#
# toolchain detection
#

if isplatform "bsd" && notisplatform "openbsd"; then
  C_COMPILERS="clang gcc cc"
  CPP_COMPILERS="clang++ g++ CC"
else
  C_COMPILERS="gcc clang suncc cc"
  CPP_COMPILERS="g++ clang++ sunCC CC"
fi
unset TOOLCHAIN
unset TOOLCHAIN_NAME
unset TOOLCHAIN_CC
unset TOOLCHAIN_CXX

check_c_compiler()
{
  command -v $1 2>&1 >/dev/null
  if [ $? -ne 0 ]; then
    return 1
  fi
  cat > "$TEMP_DIR/test.c" << __EOF__
/* test file */
#include <stdio.h>
int main(int argc, char **argv) {
#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:%d\n", __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()
{
  command -v $1 2>&1 >/dev/null
  if [ $? -ne 0 ]; then
    return 1
  fi
  cat > "$TEMP_DIR/test.cpp" << __EOF__
/* test file */
#include <iostream>
int main(int argc, char **argv) {
#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
}

create_libtest_source()
{
  # $1: filename
  # $2: optional include
  cat > "$TEMP_DIR/$1" << __EOF__
/* libtest file */
int main(int argc, char **argv) {
  return 0;
}
__EOF__
  if [ -n "$2" ]; then
    echo "#include <$2>" >> "$TEMP_DIR/$1"
  fi
}

check_c_lib()
{
  # $1: libname
  # $2: optional include
  if [ -z "$TOOLCHAIN_CC" ]; then
    return 1
  fi
  create_libtest_source "test.c" "$2"
  rm -f "$TEMP_DIR/checklib"
  $TOOLCHAIN_CC -o "$TEMP_DIR/checklib" $CFLAGS $LDFLAGS "-l$1" "$TEMP_DIR/test.c" 2> /dev/null
}

check_cpp_lib()
{
  # $1: libname
  # $2: optional include
  if [ -z "$TOOLCHAIN_CXX" ]; then
    return 1
  fi
  create_libtest_source "test.cpp" "$2"
  rm -f "$TEMP_DIR/checklib"
  $TOOLCHAIN_CXX -o "$TEMP_DIR/checklib" $CXXFLAGS $LDFLAGS "-l$1" "$TEMP_DIR/test.cpp" 2> /dev/null
}

check_lib()
{
  # $1: libname
  # $2: optional include
  if [ -n "$TOOLCHAIN_CC" ]; then
    check_c_lib "$1" "$2"
  elif  [ -n "$TOOLCHAIN_CXX" ]; then
    check_cpp_lib "$1" "$2"
  fi
}

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"
      TOOLCHAIN=`grep '^toolchain:' "$TEMP_DIR/checkcc_out" | tail -c +11`
      TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
      TOOLCHAIN_WSIZE=`grep '^wsize:' "$TEMP_DIR/checkcc_out" | tail -c +7`
      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"
        TOOLCHAIN=`grep '^toolchain:' "$TEMP_DIR/checkcc_out" | tail -c +11`
        TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
        TOOLCHAIN_WSIZE=`grep '^wsize:' "$TEMP_DIR/checkcc_out" | tail -c +7`
        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"
      TOOLCHAIN=`grep '^toolchain:' "$TEMP_DIR/checkcc_out" | tail -c +11`
      TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
      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"
        TOOLCHAIN=`grep '^toolchain:' "$TEMP_DIR/checkcc_out" | tail -c +11`
        TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
        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