dnsmasq: rework network interface ignore
[openwrt/staging/jow.git] / scripts / ext-toolchain.sh
index 616b54f21f04c808307d098dd508cec371558c17..1fa2e952bb792eea53082f1b457b5bfc62f4948b 100755 (executable)
@@ -3,7 +3,7 @@
 #   Script for various external toolchain tasks, refer to
 #   the --help output for more information.
 #
-#   Copyright (C) 2012 Jo-Philipp Wich <jow@openwrt.org>
+#   Copyright (C) 2012 Jo-Philipp Wich <jo@mein.io>
 #
 #   This program is free software; you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@ CFLAGS=""
 TOOLCHAIN="."
 
 LIBC_TYPE=""
+GCC_VERSION=""
 
 
 # Library specs
@@ -35,9 +36,11 @@ LIB_SPECS="
        rt:       librt-* librt
        pthread:  libpthread-* libpthread
        stdcpp:   libstdc++
+       thread_db: libthread-db
        gcc:      libgcc_s
        ssp:      libssp
        gfortran: libgfortran
+       gomp:     libgomp
 "
 
 # Binary specs
@@ -48,6 +51,7 @@ BIN_SPECS="
        gdbserver: gdbserver
 "
 
+OVERWRITE_CONFIG=""
 
 test_c() {
        cat <<-EOT | "${CC:-false}" $CFLAGS -o /dev/null -x c - 2>/dev/null
@@ -91,7 +95,7 @@ test_uclibc() {
        local sysroot="$("$CC" $CFLAGS -print-sysroot 2>/dev/null)"
        if [ -d "${sysroot:-$TOOLCHAIN}" ]; then
                local lib
-               for lib in "${sysroot:-$TOOLCHAIN}"/{lib,usr/lib,usr/local/lib}/ld-uClibc*.so*; do
+               for lib in "${sysroot:-$TOOLCHAIN}"/{lib,usr/lib,usr/local/lib}/ld*-uClibc*.so*; do
                        if [ -f "$lib" ] && [ ! -h "$lib" ]; then
                                return 0
                        fi
@@ -196,6 +200,60 @@ find_bins() {
        return 1
 }
 
+find_gcc_version() {
+       if [ -f $TOOLCHAIN/info.mk ]; then
+               GCC_VERSION=$(grep GCC_VERSION $TOOLCHAIN/info.mk | sed 's/GCC_VERSION=//')
+               return 0
+       fi
+
+       echo "Warning! Can't find info.mk, trying to detect with alternative way."
+
+       # Very fragile detection
+       GCC_VERSION=$(find $TOOLCHAIN/bin | grep -oE "gcc-[0-9]+\.[0-9]+\.[0-9]+$" | \
+               head -1 | sed 's/gcc-//')
+}
+
+
+wrap_bin_cc() {
+       local out="$1"
+       local bin="$2"
+
+       echo    '#!/bin/sh'                                                > "$out"
+       echo    'for arg in "$@"; do'                                     >> "$out"
+       echo    ' case "$arg" in -l*|-L*|-shared|-static)'                >> "$out"
+       echo -n '  exec "'"$bin"'" '"$CFLAGS"' ${STAGING_DIR:+'           >> "$out"
+       echo -n '-idirafter "$STAGING_DIR/usr/include" '                  >> "$out"
+       echo -n '-L "$STAGING_DIR/usr/lib" '                              >> "$out"
+       echo    '-Wl,-rpath-link,"$STAGING_DIR/usr/lib"} "$@" ;;'         >> "$out"
+       echo    ' esac'                                                   >> "$out"
+       echo    'done'                                                    >> "$out"
+       echo -n 'exec "'"$bin"'" '"$CFLAGS"' ${STAGING_DIR:+'             >> "$out"
+       echo    '-idirafter "$STAGING_DIR/usr/include"} "$@"'             >> "$out"
+
+       chmod +x "$out"
+}
+
+wrap_bin_ld() {
+       local out="$1"
+       local bin="$2"
+
+       echo    '#!/bin/sh'                                                > "$out"
+       echo -n 'exec "'"$bin"'" ${STAGING_DIR:+'                         >> "$out"
+       echo -n '-L "$STAGING_DIR/usr/lib" '                              >> "$out"
+       echo    '-rpath-link "$STAGING_DIR/usr/lib"} "$@"'                >> "$out"
+
+       chmod +x "$out"
+}
+
+wrap_bin_other() {
+       local out="$1"
+       local bin="$2"
+
+       echo    '#!/bin/sh'                                                > "$out"
+       echo    'exec "'"$bin"'" "$@"'                                    >> "$out"
+
+       chmod +x "$out"
+}
 
 wrap_bins() {
        if probe_cc; then
@@ -205,28 +263,24 @@ wrap_bins() {
                for cmd in "${CC%-*}-"*; do
                        if [ -x "$cmd" ]; then
                                local out="$1/${cmd##*/}"
+                               local bin="$cmd"
+
+                               if [ -x "$out" ] && ! grep -q STAGING_DIR "$out"; then
+                                       mv "$out" "$out.bin"
+                                       bin='$(dirname "$0")/'"${out##*/}"'.bin'
+                               fi
 
-                               echo '#!/bin/sh' > "$out"
                                case "${cmd##*/}" in
                                        *-*cc|*-*cc-*|*-*++|*-*++-*|*-cpp)
-                                               echo -n 'exec "'"$cmd"'" '"$CFLAGS"' '         >> "$out"
-                                               echo -n '${STAGING_DIR:+-idirafter '           >> "$out"
-                                               echo -n '"$STAGING_DIR/usr/include" '          >> "$out"
-                                               echo -n '-L "$STAGING_DIR/usr/lib" '           >> "$out"
-                                               echo -n '-Wl,-rpath-link,'                     >> "$out"
-                                               echo    '"$STAGING_DIR/usr/lib"} "$@"'         >> "$out"
+                                               wrap_bin_cc "$out" "$bin"
                                        ;;
                                        *-ld)
-                                               echo -n 'exec "'"$cmd"'" ${STAGING_DIR:+'      >> "$out"
-                                               echo -n '-L "$STAGING_DIR/usr/lib" '           >> "$out"
-                                               echo -n '-rpath-link '                         >> "$out"
-                                               echo    '"$STAGING_DIR/usr/lib"} "$@"'         >> "$out"
+                                               wrap_bin_ld "$out" "$bin"
                                        ;;
                                        *)
-                                               echo "exec '$cmd' \"\$@\"" >> "$out"
+                                               wrap_bin_other "$out" "$bin"
                                        ;;
                                esac
-                               chmod +x "$out"
                        fi
                done
 
@@ -242,8 +296,11 @@ print_config() {
        local mksubtarget
 
        local target="$("$CC" $CFLAGS -dumpmachine)"
+       local version="$("$CC" $CFLAGS -dumpversion)"
        local cpuarch="${target%%-*}"
-       local prefix="${CC##*/}"; prefix="${prefix%-*}-"
+
+       # get CC; strip version; strip gcc and add - suffix
+       local prefix="${CC##*/}"; prefix="${prefix%-$version}"; prefix="${prefix%-*}-"
        local config="${0%/scripts/*}/.config"
 
        # if no target specified, print choice list and exit
@@ -278,9 +335,13 @@ print_config() {
        fi
 
        # bail out if there is a .config already
-       if [ -f "${0%/scripts/*}/.config" ]; then
-               echo "There already is a .config file, refusing to overwrite!" >&2
-               return 1
+       if [ -f "$config" ]; then
+               if [ "$OVERWRITE_CONFIG" == "" ]; then
+                       echo "There already is a .config file, refusing to overwrite!" >&2
+                       return 1
+               else
+                       echo "There already is a .config file, trying to overwrite!"
+               fi
        fi
 
        case "$mktarget" in */*)
@@ -288,8 +349,11 @@ print_config() {
                mktarget="${mktarget%/*}"
        ;; esac
 
+       if [ ! -f "$config" ]; then
+               touch "$config"
+       fi
 
-       echo "CONFIG_TARGET_${mktarget}=y" > "$config"
+       echo "CONFIG_TARGET_${mktarget}=y" >> "$config"
 
        if [ -n "$mksubtarget" ]; then
                echo "CONFIG_TARGET_${mktarget}_${mksubtarget}=y" >> "$config"
@@ -308,9 +372,9 @@ print_config() {
        fi
 
        if test_feature "locale"; then
-               echo "CONFIG_NLS=y" >> "$config"
+               echo "CONFIG_BUILD_NLS=y" >> "$config"
        else
-               echo "# CONFIG_NLS is not set" >> "$config"
+               echo "# CONFIG_BUILD_NLS is not set" >> "$config"
        fi
 
        echo "CONFIG_DEVEL=y" >> "$config"
@@ -319,8 +383,29 @@ print_config() {
        echo "CONFIG_TOOLCHAIN_PREFIX=\"$prefix\"" >> "$config"
        echo "CONFIG_TARGET_NAME=\"$target\"" >> "$config"
 
+       if [ -f "$config" ]; then
+               sed -i '/CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_MUSL/d' "$config"
+               sed -i '/CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_GLIBC/d' "$config"
+       fi
+
+       if [ "$LIBC_TYPE" == glibc ]; then
+               echo "CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_GLIBC=y" >> "$config"
+       elif [ "$LIBC_TYPE" == musl ]; then
+               echo "CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_MUSL=y" >> "$config"
+       else
+               echo "Can't detect LIBC type. Aborting!" >&2
+               return 1
+       fi
+
+       if [ -n "$GCC_VERSION" ]; then
+               echo "CONFIG_EXTERNAL_GCC_VERSION=\"$GCC_VERSION\"" >> "$config"
+       else
+               echo "Can't detect GCC version. Aborting!" >&2
+               return 1
+       fi
+
        local lib
-       for lib in C RT PTHREAD GCC STDCPP SSP GFORTRAN; do
+       for lib in C RT PTHREAD GCC STDCPP SSP GFORTRAN GOMP; do
                local file
                local spec=""
                local llib="$(echo "$lib" | sed -e 's#.*#\L&#')"
@@ -409,6 +494,13 @@ probe_cpp() {
 }
 
 probe_libc() {
+       if [ -f $TOOLCHAIN/info.mk ]; then
+               LIBC_TYPE=$(grep LIBC_TYPE $TOOLCHAIN/info.mk | sed 's/LIBC_TYPE=//')
+               return 0
+       fi
+
+       echo "Warning! Can't find info.mk, trying to detect with alternative way."
+
        if [ -z "$LIBC_TYPE" ]; then
                if test_uclibc; then
                        LIBC_TYPE="uclibc"
@@ -486,8 +578,14 @@ while [ -n "$1" ]; do
                        exit $?
                ;;
 
+               --overwrite-config)
+                       OVERWRITE_CONFIG=y
+               ;;
+
                --config)
                        if probe_cc; then
+                               probe_libc
+                               find_gcc_version
                                print_config "$1"
                                exit $?
                        fi
@@ -526,7 +624,9 @@ while [ -n "$1" ]; do
                        echo -e "  Most commands also take a --cflags parameter which " >&2
                        echo -e "  is used to specify C flags to be passed to the "     >&2
                        echo -e "  cross compiler when performing tests."               >&2
-                       echo -e "  This paremter may be repeated multiple times."       >&2
+                       echo -e "  This parameter may be repeated multiple times."      >&2
+                       echo -e "  Use --overwrite-config before --config to overwrite" >&2
+                       echo -e "  an already present config with the required changes.">&2
                        exit 1
                ;;