Edit

kc3-lang/kc3/config.subr

Branch :

  • config.subr
  • #!/bin/sh
    ## kc3
    ## Copyright from 2022 to 2025 kmx.io <contact@kmx.io>
    ##
    ## Permission is hereby granted to use this software granted the above
    ## copyright notice and this permission paragraph are included in all
    ## copies and substantial portions of this software.
    ##
    ## THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
    ## PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
    ## AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
    ## THIS SOFTWARE.
    
    set -e
    
    VER_MAJOR="0"
    VER_MINOR="0"
    VER_PATCH="0"
    
    bool() {
        case "$2" in
            false|no|0) eval "$1=false";;
            true|yes|1) eval "$1=true";;
            *)          echo "invalid bool $1 $2" >&2; exit 1
        esac
    }
    
    build_lib() {
        build_lib_shared
    }
    
    build_lib_shared() {
        {
            echo
            echo "$LIB_ASAN$SHARED_PATCH: $OBJECTS_ASAN build_lib_asan"
            echo "	./build_lib_asan $LIB_ASAN$SHARED_PATCH"
            echo "$LIB_ASAN$SHARED_MINOR: $LIB_ASAN$SHARED_PATCH"
            echo "	ln -sf $LIB_ASAN$SHARED_PATCH $LIB_ASAN$SHARED_MINOR"
            echo "$LIB_ASAN$SHARED_MAJOR: $LIB_ASAN$SHARED_PATCH"
            echo "	ln -sf $LIB_ASAN$SHARED_PATCH $LIB_ASAN$SHARED_MAJOR"
            echo "$LIB_ASAN.$SHARED_EXT: $LIB_ASAN$SHARED_PATCH"
            echo "	ln -sf $LIB_ASAN$SHARED_PATCH $LIB_ASAN.$SHARED_EXT"
            echo "$LIB_ASAN: $LIB_ASAN.$SHARED_EXT $LIB_ASAN$SHARED_MAJOR $LIB_ASAN$SHARED_MINOR $LIB_ASAN$SHARED_PATCH"
            echo
            echo "$LIB_COV$SHARED_PATCH: $OBJECTS_COV build_lib_cov"
            echo "	./build_lib_cov $LIB_COV$SHARED_PATCH"
            echo "$LIB_COV$SHARED_MINOR: $LIB_COV$SHARED_PATCH"
            echo "	ln -sf $LIB_COV$SHARED_PATCH $LIB_COV$SHARED_MINOR"
            echo "$LIB_COV$SHARED_MAJOR: $LIB_COV$SHARED_PATCH"
            echo "	ln -sf $LIB_COV$SHARED_PATCH $LIB_COV$SHARED_MAJOR"
            echo "$LIB_COV.$SHARED_EXT: $LIB_COV$SHARED_PATCH"
            echo "	ln -sf $LIB_COV$SHARED_PATCH $LIB_COV.$SHARED_EXT"
            echo "$LIB_COV: $LIB_COV.$SHARED_EXT $LIB_COV$SHARED_MAJOR $LIB_COV$SHARED_MINOR $LIB_COV$SHARED_PATCH"
            echo
            echo "$LIB_DEBUG$SHARED_PATCH: $OBJECTS_DEBUG build_lib_debug"
            echo "	./build_lib_debug $LIB_DEBUG$SHARED_PATCH"
            echo "$LIB_DEBUG$SHARED_MINOR: $LIB_DEBUG$SHARED_PATCH"
            echo "	ln -sf $LIB_DEBUG$SHARED_PATCH $LIB_DEBUG$SHARED_MINOR"
            echo "$LIB_DEBUG$SHARED_MAJOR: $LIB_DEBUG$SHARED_PATCH"
            echo "	ln -sf $LIB_DEBUG$SHARED_PATCH $LIB_DEBUG$SHARED_MAJOR"
            echo "$LIB_DEBUG.$SHARED_EXT: $LIB_DEBUG$SHARED_PATCH"
            echo "	ln -sf $LIB_DEBUG$SHARED_PATCH $LIB_DEBUG.$SHARED_EXT"
            echo "$LIB_DEBUG: $LIB_DEBUG.$SHARED_EXT $LIB_DEBUG$SHARED_MAJOR $LIB_DEBUG$SHARED_MINOR $LIB_DEBUG$SHARED_PATCH"
            echo
            echo "$LIB$SHARED_PATCH: $OBJECTS build_lib_main"
            echo "	./build_lib_main $LIB$SHARED_PATCH"
            echo "$LIB$SHARED_MINOR: $LIB$SHARED_PATCH"
            echo "	ln -sf $LIB$SHARED_PATCH $LIB$SHARED_MINOR"
            echo "$LIB$SHARED_MAJOR: $LIB$SHARED_PATCH"
            echo "	ln -sf $LIB$SHARED_PATCH $LIB$SHARED_MAJOR"
            echo "$LIB.$SHARED_EXT: $LIB$SHARED_PATCH"
            echo "	ln -sf $LIB$SHARED_PATCH $LIB.$SHARED_EXT"
            echo "$LIB: $LIB.$SHARED_EXT $LIB$SHARED_MAJOR $LIB$SHARED_MINOR $LIB$SHARED_PATCH"
            echo
            echo "install::"
            echo "	\${INSTALL} -o \${OWNER} -g \${GROUP} -m 0755 -d \\"
            echo "	    \${DESTDIR}\${prefix}/lib"
            echo "	\${INSTALL} -o \${OWNER} -g \${GROUP} -m 0644 \\"
            echo "	    $LIB$SHARED_PATCH \${DESTDIR}\${prefix}/lib"
            echo "	ln -sf $LIB$SHARED_PATCH \\"
            echo "	    \${DESTDIR}\${prefix}/lib/$LIB$SHARED_MINOR"
            echo "	ln -sf $LIB$SHARED_PATCH \\"
            echo "	    \${DESTDIR}\${prefix}/lib/$LIB$SHARED_MAJOR"
            echo "	ln -sf $LIB$SHARED_PATCH \\"
            echo "	    \${DESTDIR}\${prefix}/lib/$LIB.$SHARED_EXT"
            echo "	\${INSTALL} -o \${OWNER} -g \${GROUP} -m 0644 \\"
            echo "	    $LIB_DEBUG$SHARED_PATCH \${DESTDIR}\${prefix}/lib"
            echo "	ln -sf $LIB_DEBUG$SHARED_PATCH \\"
            echo "	    \${DESTDIR}\${prefix}/lib/$LIB_DEBUG$SHARED_MINOR"
            echo "	ln -sf $LIB_DEBUG$SHARED_PATCH \\"
            echo "	    \${DESTDIR}\${prefix}/lib/$LIB_DEBUG$SHARED_MAJOR"
            echo "	ln -sf $LIB_DEBUG$SHARED_PATCH \\"
            echo "	    \${DESTDIR}\${prefix}/lib/$LIB_DEBUG.$SHARED_EXT"
            echo
            echo "uninstall::"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB$SHARED_PATCH"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB$SHARED_MINOR"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB$SHARED_MAJOR"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB.$SHARED_EXT"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB_DEBUG$SHARED_PATCH"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB_DEBUG$SHARED_MINOR"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB_DEBUG$SHARED_MAJOR"
            echo "	rm -f \${DESTDIR}\${prefix}/lib/$LIB_DEBUG.$SHARED_EXT"
        } >> ${CONFIG_MK}
    }
    
    build_o() {
        build_o_c
    }
    
    build_o_c() {
        for S in $SOURCES; do
            SRC="${SRC_DIR}/${S}"
    
            echo >> ${CONFIG_MK}
            SRC_ASAN_O="$(c2ext .asan.o "$S")"
            c_ext_rule .asan.o "$S" build_c_asan >> ${CONFIG_MK}
            echo "	./build_c_asan $SRC ${SRC_ASAN_O}" >> ${CONFIG_MK}
    
            echo >> ${CONFIG_MK}
            SRC_COV_O="$(c2ext .cov.o "$S")"
            c_ext_rule .cov.o "$S" build_c_cov >> ${CONFIG_MK}
            echo "	./build_c_cov $SRC $SRC_COV_O" >> ${CONFIG_MK}
    
            echo >> ${CONFIG_MK}
            SRC_DEBUG_O="$(c2ext .debug.o "$S")"
            c_ext_rule .debug.o "$S" build_c_debug >> ${CONFIG_MK}
            echo "	./build_c_debug $SRC $SRC_DEBUG_O" >> ${CONFIG_MK}
    
            echo >> ${CONFIG_MK}
            SRC_O="$(c2ext .main.o "$S")"
            c_ext_rule .main.o "$S" build_c_main >> ${CONFIG_MK}
            echo "	./build_c_main $SRC $SRC_O" >> ${CONFIG_MK}
        done
    }
    
    build_o_objc() {
        for S in $OBJC_SOURCES; do
            SRC="${SRC_DIR}/${S}"
    
            echo >> ${CONFIG_MK}
            SRC_ASAN_O="$(objc2ext .asan.o "$S")"
            objc_ext_rule .asan.o "$S" build_objc_asan >> ${CONFIG_MK}
            echo "	./build_objc_asan $SRC ${SRC_ASAN_O}" >> ${CONFIG_MK}
    
            echo >> ${CONFIG_MK}
            SRC_COV_O="$(objc2ext .cov.o "$S")"
            objc_ext_rule .cov.o "$S" build_objc_cov >> ${CONFIG_MK}
            echo "	./build_objc_cov $SRC $SRC_COV_O" >> ${CONFIG_MK}
    
            echo >> ${CONFIG_MK}
            SRC_DEBUG_O="$(objc2ext .debug.o "$S")"
            objc_ext_rule .debug.o "$S" build_objc_debug >> ${CONFIG_MK}
            echo "	./build_objc_debug $SRC $SRC_DEBUG_O" >> ${CONFIG_MK}
    
            echo >> ${CONFIG_MK}
            SRC_MAIN_O="$(objc2ext .main.o "$S")"
            objc_ext_rule .main.o "$S" build_objc_main >> ${CONFIG_MK}
            echo "	./build_objc_main $SRC $SRC_MAIN_O" >> ${CONFIG_MK}
        done
    }
    
    build_prog() {
        echo >> ${CONFIG_MK}
        echo "$PROG_ASAN: $OBJECTS_ASAN build_prog_asan" \
             >> ${CONFIG_MK}
        echo "	./build_prog_asan $PROG_ASAN" >> ${CONFIG_MK}
    
        echo >> ${CONFIG_MK}
        echo "$PROG_COV: $OBJECTS_COV build_prog_cov" \
             >> ${CONFIG_MK}
        echo "	./build_prog_cov $PROG_COV" >> ${CONFIG_MK}
    
        echo >> ${CONFIG_MK}
        echo "$PROG_DEBUG: $OBJECTS_DEBUG build_prog_debug" \
             >> ${CONFIG_MK}
        echo "	./build_prog_debug $PROG_DEBUG" >> ${CONFIG_MK}
    
        echo >> ${CONFIG_MK}
        echo "$PROG: $OBJECTS build_prog_main" >> ${CONFIG_MK}
        echo "	./build_prog_main $PROG" >> ${CONFIG_MK}
    }
    
    c_o_rule() {
        "$CC" $CPPFLAGS $CFLAGS -M "$SRC_DIR/$1" || {
            echo "$1" | sed -e "s,^\(.*\)\.c$,\1.o: $SRC_DIR/\1.c,"
        }
        echo "$1: $2" | sed -e 's/^\(.*\)\.c:/\1.o:/'
    }
    
    c_ext_rule() {
        c_o_rule "$2" "$3" | sed -e "s/\.o:/$1:/"
    }
    
    c_lo_rule() {
        c_ext_rule .lo "$1"
    }
    
    c_prog_rule() {
        { c_o_rule "$1" || exit 1; } | sed -e 's/[.]o:/:/'
    }
    
    c2ext() {
        EXT="$1"; shift
        echo "$@" | sed -e "s/[.]c$/${EXT}/" -e "s/[.]c /${EXT} /g"
    }
    
    c2la() {
        c2ext .la "$@"
    }
    
    c2lo() {
        c2ext .lo "$@"
    }
    
    c2o() {
        c2ext .o "$@"
    }
    
    c2prog() {
        echo "$@" | sed -e 's/[.]c$//' -e 's/[.]c / /g'
    }
    
    config_android() {
        if [ "x$HAVE_ANDROID" = "x" ]; then
            if [ -f /system/lib64/libGLESv2.so ]; then
                HAVE_ANDROID=true
            else
                HAVE_ANDROID=false
            fi
        else
            bool HAVE_ANDROID "$HAVE_ANDROID"
        fi
        echo "HAVE_ANDROID = $HAVE_ANDROID" >> ${CONFIG_MK}
        if $HAVE_ANDROID; then
            config_define HAVE_ANDROID 1
        fi
    }
    
    config_asan() {
        if uname | grep -iq netbsd; then
            HAVE_ASAN=false
            echo "HAVE_ASAN = false" >> ${CONFIG_MK}
    	return
        fi
        OUT_C=".config_ASAN.c"
        OUT=".config_ASAN"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <stdlib.h>" >> "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  void *x = malloc(1);" >> "$OUT_C"
        echo "  free(x);" >> "$OUT_C"
        echo "  return 0;" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 -fsanitize=address -fno-omit-frame-pointer \
                 "$OUT_C" ${LIBS} -lasan -o "$OUT" >/dev/null 2>&1; then
            HAVE_ASAN=true
            echo "HAVE_ASAN = true" >> ${CONFIG_MK}
        else
            HAVE_ASAN=false
            echo "HAVE_ASAN = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_C"
    }
    
    config_cocoa() {
        OUT_M=".config_COCOA.m"
        OUT=".config_COCOA"
        echo "/* generated by configure */" > "$OUT_M"
        echo "#import <Cocoa/Cocoa.h>" >> "$OUT_M"
        echo "int main (void) { return 0; }" >> "$OUT_M"
        if ${OBJC} ${OBJCFLAGS} \
                   "$OUT_M" ${LIBS} -framework Cocoa \
                   -o "$OUT" >/dev/null 2>&1; then
            eval "HAVE_COCOA=true"
            echo "HAVE_COCOA = true" >> "${CONFIG_MK}"
            config_define HAVE_COCOA 1
            LIBS="$LIBS -framework Cocoa"
        else
            eval "HAVE_COCOA=false"
            echo "HAVE_COCOA = false" >> "${CONFIG_MK}"
        fi
        rm -f "$OUT" "$OUT_M"
    }
    
    config_define() {
        CPPFLAGS="$CPPFLAGS -D$1=$2"
    }
    
    config_fuse() {
        OUT=".config_fuse"
        OUT_C=".config_fuse.c"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#define FUSE_USE_VERSION 26" >> "$OUT_C"
        echo "#include <fuse.h>" >> "$OUT_C"
        echo "#include <fuse_opt.h>" >> "$OUT_C"
        echo "int main (int argc, char **argv) {" >> "$OUT_C"
        echo "  struct fuse_operations ops;" >> "$OUT_C"
        echo "  return fuse_main(argc, argv, &ops);" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" -o "$OUT"; then
            config_define HAVE_FUSE 1
            HAVE_FUSE=true
        else
            HAVE_FUSE=false
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_gnu() {
        if grep -q _GNU_SOURCE /usr/include/features.h >/dev/null 2>&1; then
    	CFLAGS="$CFLAGS -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_BSD_SOURCE"
        fi
    }
    
    config_have() {
        if "$2"; then
            config_define "HAVE_$1" 1
        fi
        eval "HAVE_$1=$2"
    }
    
    config_have_bcrypt() {
        OUT=".config_have_bcrypt"
        OUT_C=".config_have_bcrypt.c"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <pwd.h>" >> "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  char *salt = bcrypt_gensalt(12);" >> "$OUT_C"
        echo "  return 0;" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" -o "$OUT"; then
            config_define HAVE_BCRYPT 1
            HAVE_BCRYPT=true
        else
            HAVE_BCRYPT=false
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_have_crypt_newhash() {
        OUT_C=".config_have_crypt_newhash.c"
        OUT_O=".config_have_crypt_newhash.o"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <pwd.h>" >> "$OUT_C"
        echo "#include <unistd.h>" >> "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  char hash[_PASSWORD_LEN];" >> "$OUT_C"
        echo "  return crypt_newhash(\"123\", \"bcrypt,a\", hash, sizeof(hash));" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} -c "$OUT_C" \
                 -o "$OUT_O" >/dev/null 2>&1; then
            config_define HAVE_CRYPT_NEWHASH 1
            HAVE_CRYPT_NEWHASH=true
        else
            HAVE_CRYPT_NEWHASH=false
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_have_explicit_bzero() {
        OUT=".config_have_explicit_bzero"
        OUT_C=".config_have_explicit_bzero.c"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <string.h>" >> "$OUT_C"
        echo "#include <strings.h>" >> "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  char str[8] = {0};" >> "$OUT_C"
        echo "  explicit_bzero(str, sizeof(str));" >> "$OUT_C"
        echo "  return 0;" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" -o "$OUT" >/dev/null 2>&1; then
            config_define HAVE_EXPLICIT_BZERO 1
            HAVE_EXPLICIT_BZERO=true
        else
            HAVE_EXPLICIT_BZERO=false
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_have_generic_sw_uw() {
        OUT=".config_have_generic_sw_uw"
        OUT_C=".config_have_generic_sw_uw.c"
        echo "/* generated by configure */" > "$OUT_C"
        echo "
    #include <libkc3/types.h>
    int main (void)
    {
      sw s = 1;
      uw u = 1;
      return (_Generic(s,
                       s32:  s + 1,
                       s64:  s + 2,
                       sw:   0,
                       u32:  s + 3,
                       u64:  s + 4,
                       uw:   s + 5,
                       default: s + 6) +
              _Generic(u,
                       s32:  u + 1,
                       s64:  u + 2,
                       sw:   u + 3,
                       u32:  u + 4,
                       u64:  u + 5,
                       uw:   0,
                       default: u + 6));
    }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" -o "$OUT" >/dev/null 2>&1 && \
                ./"$OUT" >/dev/null 2>&1; then
            config_define HAVE_GENERIC_SW_UW 1
            eval "HAVE_GENERIC_SW_UW=Yes"
        else
            eval "HAVE_GENERIC_SW_UW=No"
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_have_pthread() {
        if [ "x$(uname)" = "xDarwin" ]; then
            config_have PTHREAD false
        else
    	if uname -s | grep -qi mingw; then
                config_have PTHREAD false
    	else
                config_have PTHREAD true
    	fi
        fi
    }
    
    config_have_quadmath() {
        OUT_C=".config_have_quadmath.c"
        OUT=".config_have_quadmath"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <quadmath.h>" >> "$OUT_C"
        echo "int main (void) { return 0; }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" ${LDFLAGS} ${LIBS} $@ \
                 -o "$OUT" >/dev/null 2>&1; then
            config_define HAVE_QUADMATH 1
            echo "HAVE_QUADMATH = true" >> ${CONFIG_MK}
            HAVE_QUADMATH=true
        else
            echo "HAVE_QUADMATH = false" >> ${CONFIG_MK}
            HAVE_QUADMATH=false
        fi
        rm -f "$OUT" "$OUT_C"
    }
    
    config_have_f80() {
        OUT_C=".config_have_f80.c"
        OUT=".config_have_f80"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <stdio.h>" >> "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  long double x = 1.0L;" >> "$OUT_C"
        echo "  long double y = 2.0L;" >> "$OUT_C"
        echo "  long double z = x / y;" >> "$OUT_C"
        echo "  /* Check if long double has more precision than double */" >> "$OUT_C"
        echo "  if (sizeof(long double) > sizeof(double)) {" >> "$OUT_C"
        echo "    return 0;" >> "$OUT_C"
        echo "  }" >> "$OUT_C"
        echo "  return 1;" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" ${LDFLAGS} ${LIBS} $@ \
                 -o "$OUT" >/dev/null 2>&1 && \
                ./"$OUT" >/dev/null 2>&1; then
            config_define HAVE_F80 1
            echo "HAVE_F80 = true" >> ${CONFIG_MK}
            HAVE_F80=true
        else
            echo "HAVE_F80 = false" >> ${CONFIG_MK}
            HAVE_F80=false
        fi
        rm -f "$OUT" "$OUT_C"
    }
    
    config_have_float128() {
        OUT_C=".config_have_float128.c"
        OUT=".config_have_float128"
        echo "/* generated by configure */" > "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  __float128 x = 0.0Q;" >> "$OUT_C"
        echo "  return x != 0.0Q;" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" ${LDFLAGS} ${LIBS} $@ \
                 -o "$OUT" >/dev/null 2>&1; then
            config_define HAVE_FLOAT128 1
            echo "HAVE_FLOAT128 = true" >> ${CONFIG_MK}
            HAVE_FLOAT128=true
        else
            echo "HAVE_FLOAT128 = false" >> ${CONFIG_MK}
            HAVE_FLOAT128=false
        fi
        rm -f "$OUT" "$OUT_C"
    }
    
    config_have_stat_mtim() {
        OUT=".config_have_stat_mtim"
        OUT_C=".config_have_stat_mtim.c"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <sys/stat.h>" >> "$OUT_C"
        echo "#ifdef __APPLE__" >> "$OUT_C"
        echo "# define st_mtim st_mtimespec" >> "$OUT_C"
        echo "#endif" >> "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  struct stat tmp;" >> "$OUT_C"
        echo "  tmp.st_mtim.tv_sec = 0;" >> "$OUT_C"
        echo "  tmp.st_mtim.tv_nsec = 0;" >> "$OUT_C"
        echo "  return tmp.st_mtim.tv_sec + tmp.st_mtim.tv_nsec;" \
             >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" -o "$OUT"; then
            config_define HAVE_STAT_MTIM 1
            HAVE_STAT_MTIM=true
        else
            HAVE_STAT_MTIM=false
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_have_sysctl() {
        OUT=".config_have_sysctl"
        OUT_C=".config_have_sysctl.c"
        echo "/* generated by configure */" > "$OUT_C"
        echo "#include <sys/types.h>" >> "$OUT_C"
        echo "#include <sys/sysctl.h>" >> "$OUT_C"
        echo "int main (void) {" >> "$OUT_C"
        echo "  sysctl(NULL, 0, NULL, NULL, NULL, 0);" >> "$OUT_C"
        echo "  return 0;" >> "$OUT_C"
        echo "}" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" -o "$OUT"; then
            config_define HAVE_SYSCTL 1
            HAVE_SYSCTL=true
        else
            HAVE_SYSCTL=false
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_i386() {
        if [ "x$(uname -m)" = "xi386" ]; then
    	CFLAGS="$CFLAGS -msse2 -mfpmath=sse"
        fi
    }
    
    config_include() {
        OUT=".config_$1"
        OUT_C=".config_$1.c"
        shift
        echo "/* generated by configure */" > "$OUT_C"
        while [ $# -gt 1 ]; do
            echo "#include <$1>" >> "$OUT_C"
            shift
        done
        echo "int main (void) { return 0; }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" -o "$OUT"; then
            config_define "$1" 1
            eval "$1=Yes"
        else
            eval "$1=No"
        fi
        rm -f "$OUT_C"
        rm -f "$OUT"
    }
    
    config_include_have() {
        NAME="$1"
        shift
        OUT_C=".config_$NAME.c"
        OUT=".config_$NAME"
        echo "/* generated by configure */" > "$OUT_C"
        echo "$@" >> "$OUT_C"
        echo "int main (void) { return 0; }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" ${LIBS} -o "$OUT"; then
            eval "HAVE_$NAME=true"
            echo "HAVE_$NAME = true" >> ${CONFIG_MK}
        else
            eval "HAVE_$NAME=false"
            echo "HAVE_$NAME = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_C"
    }
    
    config_ldadd() {
        NAME="$1"
        shift
        OUT_C=".config_$NAME.c"
        OUT_O=".config_$NAME.o"
        OUT=".config_$NAME"
        echo "/* generated by configure */" > "$OUT_C"
        echo "int main (void) { return 0; }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} -c "$OUT_C" -o "$OUT_O" && \
           ${LD} ${LDFLAGS} ${PROG_LDADD} "$OUT_O" ${LIBS} $@ -o "$OUT"; then
            LDADD="$@ $LDADD"
            PROG_LDADD="$@ $PROG_LDADD"
            eval "HAVE_$NAME=true"
            echo "HAVE_$NAME = true" >> ${CONFIG_MK}
        else
            eval "HAVE_$NAME=false"
            echo "HAVE_$NAME = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_C" "$OUT_O"
    }
    
    config_lib() {
        NAME="$1"
        shift
        OUT_C=".config_$NAME.c"
        OUT_O=".config_$NAME.o"
        OUT=".config_$NAME"
        echo "/* generated by configure */" > "$OUT_C"
        echo "int main (void) { return 0; }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} -c "$OUT_C" -o "$OUT_O" && \
           ${LD} ${LDFLAGS} ${PROG_LDADD} "$OUT_O" ${LIBS} $@ -o "$OUT"; then
            LIBS="$LIBS $@"
            eval "HAVE_$NAME=true"
            echo "HAVE_$NAME = true" >> ${CONFIG_MK}
        else
            eval "HAVE_$NAME=false"
            echo "HAVE_$NAME = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_C" "$OUT_O"
    }
    
    config_lib_have() {
        NAME="$1"
        shift
        OUT_C=".config_$NAME.c"
        OUT=".config_$NAME"
        echo "/* generated by configure */" > "$OUT_C"
        echo "int main (void) { return 0; }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} \
                 "$OUT_C" ${LDFLAGS} ${LIBS} $@ -o "$OUT"; then
            eval "HAVE_$NAME=true"
            echo "HAVE_$NAME = true" >> ${CONFIG_MK}
        else
            eval "HAVE_$NAME=false"
            echo "HAVE_$NAME = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_C"
    }
    
    config_openmp() {
        OUT_C=".config_openmp.c"
        OUT_O=".config_openmp.o"
        OUT=".config_openmp"
        echo "/* generated by configure */" > "$OUT_C"
        echo "int main (void) { return 0; }" >> "$OUT_C"
        if ${CC} ${CPPFLAGS} ${CFLAGS} -fopenmp -c "$OUT_C" \
                 -o "$OUT_O" && ${LD} ${LDFLAGS} "$OUT_O" ${LIBS} -lomp \
                                      ${PROG_LDADD} -o "$OUT"; then
            CFLAGS="$CFLAGS -fopenmp"
            LIBS="$LIBS -lomp"
            HAVE_OPENMP=true
            echo "HAVE_OPENMP = true" >> ${CONFIG_MK}
        else
            HAVE_OPENMP=false
            echo "HAVE_OPENMP = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_C" "$OUT_O"
    }
    
    config_no_undefined() {
        if [ "x$(uname -s)" = "xFreeBSD" -o \
             "x$(uname -s)" = "xOpenBSD" ]; then
            return 0
        fi
        OUT=".config_no_undefined"
        OUT_C=".config_no_undefined.c"
        OUT_O=".config_no_undefined.o"
        echo "/* generated by configure */" > "$OUT_C"
        echo "int main (void) { return 0; }" >> "$OUT_C"
        ${CC} ${CPPFLAGS} ${CFLAGS} -c "$OUT_C" -o "$OUT_O"
        if ${LD} ${LDFLAGS} --no-undefined "$OUT_O" ${LIBS} ${PROG_LDADD} \
                 -o "$OUT" >/dev/null 2>&1; then
            LDFLAGS="$LDFLAGS --no-undefined"
        fi
        rm -f "$OUT" "$OUT_C" "$OUT_O"
    }
    
    config_objc_include_have() {
        NAME="$1"
        shift
        OUT_M=".config_$NAME.m"
        OUT=".config_$NAME"
        echo "/* generated by configure */" > "$OUT_M"
        echo "$@" >> "$OUT_M"
        echo "int main (void) { return 0; }" >> "$OUT_M"
        if ${OBJC} ${OBJCFLAGS} \
                   "$OUT_M" ${LIBS} -o "$OUT"; then
            eval "HAVE_$NAME=true"
            echo "HAVE_$NAME = true" >> ${CONFIG_MK}
        else
            eval "HAVE_$NAME=false"
            echo "HAVE_$NAME = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_M"
    }
    
    config_objc_lib() {
        NAME="$1"
        shift
        OUT_M=".config_$NAME.m"
        OUT=".config_$NAME"
        echo "/* generated by configure */" > "$OUT_M"
        echo "int main (void) { return 0; }" >> "$OUT_M"
        if ${OBJC} ${CPPFLAGS} ${OBJCFLAGS} \
                   "$OUT_M" ${LDFLAGS} ${LIBS} $@ \
                   -o "$OUT"; then
            LIBS="$LIBS $@"
        fi
        rm -f "$OUT" "$OUT_M"
    }
    
    config_objc_lib_have() {
        NAME="$1"
        shift
        OUT_M=".config_$NAME.m"
        OUT=".config_$NAME"
        echo "/* generated by configure */" > "$OUT_M"
        echo "int main (void) { return 0; }" >> "$OUT_M"
        if ${OBJC} ${CPPFLAGS} ${OBJCFLAGS} \
                   "$OUT_M" ${LIBS} $@ -o "$OUT"; then
            eval "HAVE_$NAME=true"
            echo "HAVE_$NAME = true" >> ${CONFIG_MK}
        else
            eval "HAVE_$NAME=false"
            echo "HAVE_$NAME = false" >> ${CONFIG_MK}
        fi
        rm -f "$OUT" "$OUT_M"
    }
    
    config_prog() {
        PROG="$1"
        PROG_ASAN="${PROG}_asan"
        PROG_COV="${PROG}_cov"
        PROG_DEBUG="${PROG}_debug"
        echo "PROG       = ${PROG}"       >> ${CONFIG_MK}
        echo "PROG_ASAN  = ${PROG_ASAN}"  >> ${CONFIG_MK}
        echo "PROG_COV   = ${PROG_COV}"   >> ${CONFIG_MK}
        echo "PROG_DEBUG = ${PROG_DEBUG}" >> ${CONFIG_MK}
        CPPFLAGS="$CPPFLAGS -DPREFIX=\"\\\"${PREFIX}\\\"\""
    }
    
    config_subdirs() {
        for SUBDIR; do
            if [ "x$SUBDIR" = "x" -o \
                 "x$SRC_DIR" = "x" ]; then
                echo "$0: config_subdirs: missing configuration" >&2
                exit 1
            fi
            SUBDIR_SH="$(sh_quote "$SUBDIR")"
            echo "( mkdir -p $SUBDIR_SH && cd $SUBDIR_SH && $SRC_DIR/$SUBDIR/configure; )"
        done | runj -1 /bin/sh
    }
    
    config_win32() {
        if uname -s | grep -qi mingw32; then
    	HAVE_WIN32=true
    	CPPFLAGS="$CPPFLAGS -mwin32 -municode -DWIN32"
            LDFLAGS="$LDFLAGS --export-all-symbols"
        else
    	HAVE_WIN32=false
        fi
        echo "HAVE_WIN32 = ${HAVE_WIN32}" >> ${CONFIG_MK}
    }
    
    config_win64() {
        if uname -s | grep -qi mingw64; then
    	HAVE_WIN32=true
    	HAVE_WIN64=true
    	CPPFLAGS="$CPPFLAGS -DWIN32 -DWIN64"
            LDFLAGS="$LDFLAGS --export-all-symbols"
        else
    	HAVE_WIN64=false
        fi
        echo "HAVE_WIN32 = ${HAVE_WIN32}" >> ${CONFIG_MK}
        echo "HAVE_WIN64 = ${HAVE_WIN64}" >> ${CONFIG_MK}
    }
    
    cpp_o_rule() {
        "$CXX" $CPPFLAGS $CXXFLAGS -M "${SRC_DIR}/$1" || {
            echo "$1" | sed -e 's/^\(.*\)\.cpp$/\1.o: \1.cpp/'
        }
        echo "$1: $2" | sed -e 's/^\(.*\)\.cpp: $/\1.o: /'
    }
    
    cpp_ext_rule() {
        cpp_o_rule "$2" "$3" | sed -e "s/[.]o:/$1:/"
    }
    
    cpp_lo_rule() {
        cpp_ext_rule .lo "$1" "$2"
    }
    
    cpp_prog_rule() {
        { cpp_o_rule "$1" "$2" || exit 1; } | sed -e 's/[.]o:/:/'
    }
    
    cpp2ext() {
        EXT="$1"; shift
        echo "$@" | sed -e "s/[.]cpp$/${EXT}/" -e "s/[.]cpp /${EXT} /g"
    }
    
    cpp2la() {
        cpp2ext .la "$@"
    }
    
    cpp2lo() {
        cpp2ext .lo "$@"
    }
    
    cpp2o() {
        cpp2ext .o "$@"
    }
    
    cpp2prog() {
        echo "$@" | sed -e 's/[.]cpp$//' -e 's/[.]cpp / /g'
    }
    
    cxx_o_rule() {
        echo "$1" | sed -e 's/^\(.*\)\.cxx$/\1.o: \1.cxx/'
        echo "$1: $2" | sed -e 's/^\(.*\)\.cxx:/\1.o:/'
    }
    
    cxx_ext_rule() {
        cxx_o_rule "$2" "$3" | sed -e "s/\.o:/$1:/"
    }
    
    cxx_lo_rule() {
        cxx_ext_rule .lo "$1"
    }
    
    cxx_prog_rule() {
        { cxx_o_rule "$1" || exit 1; } | sed -e 's/[.]o:/:/'
    }
    
    cxx2ext() {
        EXT="$1"; shift
        echo "$@" | sed -e "s/[.]cxx$/${EXT}/" -e "s/[.]cxx /${EXT} /g"
    }
    
    cxx2la() {
        cxx2ext .la "$@"
    }
    
    cxx2lo() {
        cxx2ext .lo "$@"
    }
    
    cxx2o() {
        cxx2ext .o "$@"
    }
    
    cxx2prog() {
        echo "$@" | sed -e 's/[.]cxx$//' -e 's/[.]cxx / /g'
    }
    
    env_reset() {
        CPPFLAGS="$ENV_CPPFLAGS"
        CFLAGS="$ENV_CFLAGS"
        CXXFLAGS="$ENV_CXXFLAGS"
        LDFLAGS="$ENV_LDFLAGS"
        LIBS="$ENV_LIBS"
    }
    
    objc_o_rule() {
        OBJC_O_RULE_ARG="$(echo "$1" | sed -e 's/^\(.*\)\.m$/\1/')"
        echo "${OBJC_O_RULE_ARG}.o: ${SRC_DIR}/${OBJC_O_RULE_ARG}.m"
        echo "${OBJC_O_RULE_ARG}.o: ${SRC_DIR}/$2"
    }
    
    objc_ext_rule() {
        objc_o_rule "$2" "$3" | sed -e "s/\.o:/$1:/"
    }
    
    objc2ext() {
        EXT="$1"; shift
        echo "$@" | sed -e "s/[.]m$/${EXT}/" -e "s/[.]m /${EXT} /g"
    }
    
    pkg_config() {
        NAME=$(echo $1 | tr '[a-z-]' '[A-Z_]')
        if pkg-config "$1"; then
    	CFLAGS="$CFLAGS $(pkg-config --cflags "$1")"
    	CXXFLAGS="$CXXFLAGS $(pkg-config --cflags "$1")"
    	LIBS="$LIBS $(pkg-config --libs "$1" |
                              sed -e 's/-Wl,//g' -e 's/,/ /g')"
            echo "HAVE_$NAME = true" >> "${CONFIG_MK}"
            config_define "HAVE_$NAME" 1
        fi
    }
    
    require_pkg_config() {
        if ! which pkg-config >/dev/null; then
            echo "please install pkg-config" >&2
            exit 1
        fi
    }
    
    sh_quote() {
        printf '"'
        {
    	printf "%s" "$1"
    	shift
    	for ARG; do
    	    printf " %s" "$ARG"
    	done
        } | sed -e 's,\(["\\]\),\\\1,g'
        printf '"\n'
    }
    
    sources() {
        SOURCES_TMP="$(echo "$2" | kmx_sort -u | grep -Ev -e '~$' -e '/\.#')"
        echo "$1 = \\
    $(echo "$SOURCES_TMP" | sed -e 's/^\(.*\)$/	"\1" \\/')
    " >> ${SOURCES_MK}
        echo "$1='$(echo "$SOURCES_TMP" | tr '\n' ' ')'" >> ${SOURCES_SH}
    }
    
    swift_o_rule() {
        echo "$1" | sed -e 's/^\(.*\)\.swift$/\1.o: \1.c/'
        echo "$1" | sed -e 's/^\(.*\)\.swift$/\1.o: Makefile config.mk/'
    }
    
    swift_ext_rule() {
        swift_o_rule "$2" | sed -e "s/[.]o:/$1:/"
    }
    
    swift2ext() {
        EXT="$1"; shift
        echo "$@" | sed -e "s/[.]swift$/${EXT}/" -e "s/[.]swift /${EXT} /g"
    }
    
    update_and_chmod() {
        if ! cmp "$2" "$3" >/dev/null 2>&1; then
            mv "$2" "$3"
            echo "-> ${PWD}/$3"
        else
            rm "$2"
        fi
        chmod "$1" "$3"
    }
    
    update_build() {
        update_build_c
    }
    
    update_build_c() {
        BUILD_C_MAIN=build_c_main.tmp
        BUILD_C_ASAN=build_c_asan.tmp
        BUILD_C_COV=build_c_cov.tmp
        BUILD_C_DEBUG=build_c_debug.tmp
        mkdir -p .build
    
        COMPILE="\${CC} \${CPPFLAGS} \${CFLAGS}"
        COMPILE="$COMPILE -c \"\$1\" -o \"\$2\""
    
        if [ "x${PROG}" != "x" ]; then
            CPPFLAGS="${CPPFLAGS} -DPROG=\\\"${PROG}\\\""
            CPPFLAGS_ASAN="${CPPFLAGS_ASAN} -DPROG=\\\"${PROG_ASAN}\\\""
            CPPFLAGS_COV="${CPPFLAGS_COV} -DPROG=\\\"${PROG_COV}\\\""
            CPPFLAGS_DEBUG="${CPPFLAGS_DEBUG} -DPROG=\\\"${PROG_DEBUG}\\\""
        fi
    
        echo "#!/bin/sh" >> ${BUILD_C_ASAN}
        echo "# generated by configure" >> ${BUILD_C_ASAN}
        echo "LOG=\".build/\$(basename \"\$1\").asan.log\"" >> ${BUILD_C_ASAN}
        echo "export CC=\"${CC}\"" >> ${BUILD_C_ASAN}
        echo "export CPPFLAGS=\"${CPPFLAGS_ASAN}\"" >> ${BUILD_C_ASAN}
        echo "export CFLAGS=\"${CFLAGS_ASAN} ${CFLAGS_HOST} ${CFLAGS_TARGET}\"" >> ${BUILD_C_ASAN}
        echo "export LD=\"${LD}\"" >> ${BUILD_C_ASAN}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_C_ASAN}
        update_and_chmod 755 ${BUILD_C_ASAN} build_c_asan
    
        echo "#!/bin/sh" >> ${BUILD_C_COV}
        echo "# generated by configure" >> ${BUILD_C_COV}
        echo "LOG=\".build/\$(basename \"\$1\").cov.log\"" >> ${BUILD_C_COV}
        echo "export CC=\"${CC}\"" >> ${BUILD_C_COV}
        echo "export CPPFLAGS=\"${CPPFLAGS_COV}\"" >> ${BUILD_C_COV}
        echo "export CFLAGS=\"${CFLAGS_COV} ${CFLAGS_HOST} ${CFLAGS_TARGET}\"" >> ${BUILD_C_COV}
        echo "export LD=\"${LD}\"" >> ${BUILD_C_COV}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_C_COV}
        update_and_chmod 755 ${BUILD_C_COV} build_c_cov
    
        echo "#!/bin/sh" >> ${BUILD_C_DEBUG}
        echo "# generated by configure" >> ${BUILD_C_DEBUG}
        echo "LOG=\".build/\$(basename \"\$1\").debug.log\"" >> ${BUILD_C_DEBUG}
        echo "export CC=\"${CC}\"" >> ${BUILD_C_DEBUG}
        echo "export CPPFLAGS=\"${CPPFLAGS_DEBUG}\"" >> ${BUILD_C_DEBUG}
        echo "export CFLAGS=\"${CFLAGS_DEBUG}\" ${CFLAGS_HOST} ${CFLAGS_TARGET}" >> ${BUILD_C_DEBUG}
        echo "export LD=\"${LD}\"" >> ${BUILD_C_DEBUG}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_C_DEBUG}
        update_and_chmod 755 ${BUILD_C_DEBUG} build_c_debug
    
        echo "#!/bin/sh" >> ${BUILD_C_MAIN}
        echo "# generated by configure" >> ${BUILD_C_MAIN}
        echo "LOG=\".build/\$(basename \"\$1\").main.log\"" >> ${BUILD_C_MAIN}
        echo "export CC=\"${CC}\"" >> ${BUILD_C_MAIN}
        echo "export CPPFLAGS=\"${CPPFLAGS}\"" >> ${BUILD_C_MAIN}
        echo "export CFLAGS=\"${CFLAGS} ${CFLAGS_HOST} ${CFLAGS_TARGET}\"" >> ${BUILD_C_MAIN}
        echo "export LD=\"${LD}\"" >> ${BUILD_C_MAIN}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_C_MAIN}
        update_and_chmod 755 ${BUILD_C_MAIN} build_c_main
    }
    
    update_build_cxx() {
        BUILD_CXX_MAIN=build_cxx_main.tmp
        BUILD_CXX_ASAN=build_cxx_asan.tmp
        BUILD_CXX_COV=build_cxx_cov.tmp
        BUILD_CXX_DEBUG=build_cxx_debug.tmp
        mkdir -p .build
    
        COMPILE="\${CXX} \${CPPFLAGS} \${CXXFLAGS}"
        COMPILE="$COMPILE -c \"\$1\" -o \"\$2\""
    
        echo "#!/bin/sh" >> ${BUILD_CXX_ASAN}
        echo "# generated by configure" >> ${BUILD_CXX_ASAN}
        echo "LOG=\".build/\$(basename \"\$1\").debug.log\"" >> ${BUILD_CXX_ASAN}
        echo "export CXX=\"${CXX}\"" >> ${BUILD_CXX_ASAN}
        echo "export CPPFLAGS=\"${CPPFLAGS_ASAN}\"" >> ${BUILD_CXX_ASAN}
        echo "export CXXFLAGS=\"${CXXFLAGS_ASAN}\"" >> ${BUILD_CXX_ASAN}
        echo "export LD=\"${LD}\"" >> ${BUILD_CXX_ASAN}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_CXX_ASAN}
        update_and_chmod 755 ${BUILD_CXX_ASAN} build_cxx_asan
    
        echo "#!/bin/sh" >> ${BUILD_CXX_COV}
        echo "# generated by configure" >> ${BUILD_CXX_COV}
        echo "LOG=\".build/\$(basename \"\$1\").debug.log\"" >> ${BUILD_CXX_COV}
        echo "export CXX=\"${CXX}\"" >> ${BUILD_CXX_COV}
        echo "export CPPFLAGS=\"${CPPFLAGS_COV}\"" >> ${BUILD_CXX_COV}
        echo "export CXXFLAGS=\"${CXXFLAGS_COV}\"" >> ${BUILD_CXX_COV}
        echo "export LD=\"${LD}\"" >> ${BUILD_CXX_COV}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_CXX_COV}
        update_and_chmod 755 ${BUILD_CXX_COV} build_cxx_cov
    
        echo "#!/bin/sh" >> ${BUILD_CXX_DEBUG}
        echo "# generated by configure" >> ${BUILD_CXX_DEBUG}
        echo "LOG=\".build/\$(basename \"\$1\").debug.log\"" >> ${BUILD_CXX_DEBUG}
        echo "export CXX=\"${CXX}\"" >> ${BUILD_CXX_DEBUG}
        echo "export CPPFLAGS=\"${CPPFLAGS_DEBUG}\"" >> ${BUILD_CXX_DEBUG}
        echo "export CXXFLAGS=\"${CXXFLAGS_DEBUG}\"" >> ${BUILD_CXX_DEBUG}
        echo "export LD=\"${LD}\"" >> ${BUILD_CXX_DEBUG}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_CXX_DEBUG}
        update_and_chmod 755 ${BUILD_CXX_DEBUG} build_cxx_debug
    
        echo "#!/bin/sh" >> ${BUILD_CXX_MAIN}
        echo "# generated by configure" >> ${BUILD_CXX_MAIN}
        echo "LOG=\".build/\$(basename \"\$1\").main.log\"" >> ${BUILD_CXX_MAIN}
        echo "export CXX=\"${CXX}\"" >> ${BUILD_CXX_MAIN}
        echo "export CPPFLAGS=\"${CPPFLAGS}\"" >> ${BUILD_CXX_MAIN}
        echo "export CXXFLAGS=\"${CXXFLAGS}\"" >> ${BUILD_CXX_MAIN}
        echo "export LD=\"${LD}\"" >> ${BUILD_CXX_MAIN}
        echo "$COMPILE > \"\$LOG\" 2>&1 || $COMPILE" >> ${BUILD_CXX_MAIN}
        update_and_chmod 755 ${BUILD_CXX_MAIN} build_cxx_main
    }
    
    update_build_lib() {
        BUILD_LIB_MAIN=build_lib_main.tmp
        BUILD_LIB_ASAN=build_lib_asan.tmp
        BUILD_LIB_COV=build_lib_cov.tmp
        BUILD_LIB_DEBUG=build_lib_debug.tmp
        mkdir -p .build
    
        LINK="\${LD} \${SHARED_FLAGS} \${LDFLAGS} \${OBJECTS}"
        LINK="$LINK \${LIBS} \${LIB_LDADD} \${IMPLIB} -o \"\$1\""
    
        echo "#!/bin/sh" >> ${BUILD_LIB_ASAN}
        echo "# generated by configure" >> ${BUILD_LIB_ASAN}
        echo "LOG=\".build/\$(basename \"\$1\").asan.log\"" >> ${BUILD_LIB_ASAN}
        echo "export CC=\"${CC}\"" >> ${BUILD_LIB_ASAN}
        echo "export LD=\"${LD}\"" >> ${BUILD_LIB_ASAN}
        echo "export LIB_BASE=\"${LIB_ASAN}\"" >> ${BUILD_LIB_ASAN}
        echo "export PREFIX=\"${PREFIX}\"" >> ${BUILD_LIB_ASAN}
        echo "export VER_MAJOR=\"${VER_MAJOR}\"" >> ${BUILD_LIB_ASAN}
        echo "export VER_MINOR=\"${VER_MINOR}\"" >> ${BUILD_LIB_ASAN}
        echo "export VER_PATCH=\"${VER_PATCH}\"" >> ${BUILD_LIB_ASAN}
        echo "export SHARED_FLAGS=\"${SHARED_FLAGS}\"" >> ${BUILD_LIB_ASAN}
        echo "export IMPLIB=\"${IMPLIB}\"" >> ${BUILD_LIB_ASAN}
        echo "export CFLAGS=\"${CFLAGS_ASAN}\" ${CFLAGS_HOST} ${CFLAGS_TARGET}" >> ${BUILD_LIB_ASAN}
        echo "export LDFLAGS=\"${LDFLAGS_ASAN}\"" >> ${BUILD_LIB_ASAN}
        echo "export OBJECTS=\"${OBJECTS_ASAN}\"" >> ${BUILD_LIB_ASAN}
        echo "export LIBS=\"${LIBS_ASAN}\"" >> ${BUILD_LIB_ASAN}
        echo "export LIB_LDADD=\"${LIB_LDADD}\"" >> ${BUILD_LIB_ASAN}
        echo "export AR=\"${AR}\"" >> ${BUILD_LIB_ASAN}
        echo "export RANLIB=\"${RANLIB}\"" >> ${BUILD_LIB_ASAN}
        echo >> ${BUILD_LIB_ASAN}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_LIB_ASAN}
        update_and_chmod 755 ${BUILD_LIB_ASAN} build_lib_asan
    
        echo "#!/bin/sh" >> ${BUILD_LIB_COV}
        echo "# generated by configure" >> ${BUILD_LIB_COV}
        echo "LOG=\".build/\$(basename \"\$1\").cov.log\"" >> ${BUILD_LIB_COV}
        echo "export CC=\"${CC}\"" >> ${BUILD_LIB_COV}
        echo "export LD=\"${LD}\"" >> ${BUILD_LIB_COV}
        echo "export LIB_BASE=\"${LIB_COV}\"" >> ${BUILD_LIB_COV}
        echo "export PREFIX=\"${PREFIX}\"" >> ${BUILD_LIB_COV}
        echo "export VER_MAJOR=\"${VER_MAJOR}\"" >> ${BUILD_LIB_COV}
        echo "export VER_MINOR=\"${VER_MINOR}\"" >> ${BUILD_LIB_COV}
        echo "export VER_PATCH=\"${VER_PATCH}\"" >> ${BUILD_LIB_COV}
        echo "export SHARED_FLAGS=\"${SHARED_FLAGS}\"" >> ${BUILD_LIB_COV}
        echo "export IMPLIB=\"${IMPLIB}\"" >> ${BUILD_LIB_COV}
        echo "export CFLAGS=\"${CFLAGS_COV} ${CFLAGS_HOST} ${CFLAGS_TARGET}\"" >> ${BUILD_LIB_COV}
        echo "export LDFLAGS=\"${LDFLAGS_COV}\"" >> ${BUILD_LIB_COV}
        echo "export OBJECTS=\"${OBJECTS_COV}\"" >> ${BUILD_LIB_COV}
        echo "export LIBS=\"${LIBS_COV}\"" >> ${BUILD_LIB_COV}
        echo "export LIB_LDADD=\"${LIB_LDADD}\"" >> ${BUILD_LIB_COV}
        echo "export AR=\"${AR}\"" >> ${BUILD_LIB_COV}
        echo "export RANLIB=\"${RANLIB}\"" >> ${BUILD_LIB_COV}
        echo >> ${BUILD_LIB_COV}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_LIB_COV}
        update_and_chmod 755 ${BUILD_LIB_COV} build_lib_cov
    
        echo "#!/bin/sh" >> ${BUILD_LIB_DEBUG}
        echo "# generated by configure" >> ${BUILD_LIB_DEBUG}
        echo "LOG=\".build/\$(basename \"\$1\").debug.log\"" >> ${BUILD_LIB_DEBUG}
        echo "export CC=\"${CC}\"" >> ${BUILD_LIB_DEBUG}
        echo "export LD=\"${LD}\"" >> ${BUILD_LIB_DEBUG}
        echo "export LIB_BASE=\"${LIB_DEBUG}\"" >> ${BUILD_LIB_DEBUG}
        echo "export PREFIX=\"${PREFIX}\"" >> ${BUILD_LIB_DEBUG}
        echo "export VER_MAJOR=\"${VER_MAJOR}\"" >> ${BUILD_LIB_DEBUG}
        echo "export VER_MINOR=\"${VER_MINOR}\"" >> ${BUILD_LIB_DEBUG}
        echo "export VER_PATCH=\"${VER_PATCH}\"" >> ${BUILD_LIB_DEBUG}
        echo "export SHARED_FLAGS=\"${SHARED_FLAGS}\"" >> ${BUILD_LIB_DEBUG}
        echo "export IMPLIB=\"${IMPLIB}\"" >> ${BUILD_LIB_DEBUG}
        echo "export CFLAGS=\"${CFLAGS_DEBUG} ${CFLAGS_HOST} ${CFLAGS_TARGET}\"" >> ${BUILD_LIB_DEBUG}
        echo "export LDFLAGS=\"${LDFLAGS_DEBUG}\"" >> ${BUILD_LIB_DEBUG}
        echo "export OBJECTS=\"${OBJECTS_DEBUG}\"" >> ${BUILD_LIB_DEBUG}
        echo "export LIBS=\"${LIBS_DEBUG}\"" >> ${BUILD_LIB_DEBUG}
        echo "export LIB_LDADD=\"${LIB_LDADD}\"" >> ${BUILD_LIB_DEBUG}
        echo "export AR=\"${AR}\"" >> ${BUILD_LIB_DEBUG}
        echo "export RANLIB=\"${RANLIB}\"" >> ${BUILD_LIB_DEBUG}
        echo >> ${BUILD_LIB_DEBUG}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_LIB_DEBUG}
        update_and_chmod 755 ${BUILD_LIB_DEBUG} build_lib_debug
    
        echo "#!/bin/sh" >> ${BUILD_LIB_MAIN}
        echo "# generated by configure" >> ${BUILD_LIB_MAIN}
        echo "LOG=\".build/\$(basename \"\$1\").main.log\"" >> ${BUILD_LIB_MAIN}
        echo "export CC=\"${CC}\"" >> ${BUILD_LIB_MAIN}
        echo "export LD=\"${LD}\"" >> ${BUILD_LIB_MAIN}
        echo "export LIB_BASE=\"${LIB}\"" >> ${BUILD_LIB_MAIN}
        echo "export PREFIX=\"${PREFIX}\"" >> ${BUILD_LIB_MAIN}
        echo "export VER_MAJOR=\"${VER_MAJOR}\"" >> ${BUILD_LIB_MAIN}
        echo "export VER_MINOR=\"${VER_MINOR}\"" >> ${BUILD_LIB_MAIN}
        echo "export VER_PATCH=\"${VER_PATCH}\"" >> ${BUILD_LIB_MAIN}
        echo "export SHARED_FLAGS=\"${SHARED_FLAGS}\"" >> ${BUILD_LIB_MAIN}
        echo "export IMPLIB=\"${IMPLIB}\"" >> ${BUILD_LIB_MAIN}
        echo "export CFLAGS=\"${CFLAGS}\" ${CFLAGS_HOST} ${CFLAGS_TARGET}" >> ${BUILD_LIB_MAIN}
        echo "export LDFLAGS=\"${LDFLAGS}\"" >> ${BUILD_LIB_MAIN}
        echo "export OBJECTS=\"${OBJECTS}\"" >> ${BUILD_LIB_MAIN}
        echo "export LIBS=\"${LIBS}\"" >> ${BUILD_LIB_MAIN}
        echo "export LIB_LDADD=\"${LIB_LDADD}\"" >> ${BUILD_LIB_MAIN}
        echo "export AR=\"${AR}\"" >> ${BUILD_LIB_MAIN}
        echo "export RANLIB=\"${RANLIB}\"" >> ${BUILD_LIB_MAIN}
        echo >> ${BUILD_LIB_MAIN}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_LIB_MAIN}
        update_and_chmod 755 ${BUILD_LIB_MAIN} build_lib_main
    }
    
    update_build_objc() {
        BUILD_OBJC_MAIN=build_objc_main.tmp
        BUILD_OBJC_ASAN=build_objc_asan.tmp
        BUILD_OBJC_COV=build_objc_cov.tmp
        BUILD_OBJC_DEBUG=build_objc_debug.tmp
        COMPILE="\${OBJC} \${CPPFLAGS} \${CFLAGS} -c \"\$1\" -o \"\$2\""
        mkdir -p .build
        LOG=".build/log"
    
        echo "#!/bin/sh" >> ${BUILD_OBJC_ASAN}
        echo "# generated by configure" >> ${BUILD_OBJC_ASAN}
        echo "OBJC=\"${OBJC}\"" >> ${BUILD_OBJC_ASAN}
        echo "export CPPFLAGS=\"${CPPFLAGS_ASAN}\"" >> ${BUILD_OBJC_ASAN}
        echo "export CFLAGS=\"${CFLAGS_ASAN}\"" >> ${BUILD_OBJC_ASAN}
        echo "${COMPILE} >> ${LOG} 2>&1 || ${COMPILE}" >> ${BUILD_OBJC_ASAN}
        update_and_chmod 755 ${BUILD_OBJC_ASAN} build_objc_asan
    
        echo "#!/bin/sh" >> ${BUILD_OBJC_COV}
        echo "# generated by configure" >> ${BUILD_OBJC_COV}
        echo "OBJC=\"${OBJC}\"" >> ${BUILD_OBJC_COV}
        echo "export CPPFLAGS=\"${CPPFLAGS_COV}\"" >> ${BUILD_OBJC_COV}
        echo "export CFLAGS=\"${CFLAGS_COV}\"" >> ${BUILD_OBJC_COV}
        echo "${COMPILE} >> ${LOG} 2>&1 || ${COMPILE}" >> ${BUILD_OBJC_COV}
        update_and_chmod 755 ${BUILD_OBJC_COV} build_objc_cov
    
        echo "#!/bin/sh" >> ${BUILD_OBJC_DEBUG}
        echo "# generated by configure" >> ${BUILD_OBJC_DEBUG}
        echo "OBJC=\"${OBJC}\"" >> ${BUILD_OBJC_DEBUG}
        echo "export CPPFLAGS=\"${CPPFLAGS_DEBUG}\"" >> ${BUILD_OBJC_DEBUG}
        echo "export CFLAGS=\"${CFLAGS_DEBUG}\"" >> ${BUILD_OBJC_DEBUG}
        echo "${COMPILE} >> ${LOG} 2>&1 || ${COMPILE}" >> ${BUILD_OBJC_DEBUG}
        update_and_chmod 755 ${BUILD_OBJC_DEBUG} build_objc_debug
    
        echo "#!/bin/sh" >> ${BUILD_OBJC_MAIN}
        echo "# generated by configure" >> ${BUILD_OBJC_MAIN}
        echo "OBJC=\"${OBJC}\"" >> ${BUILD_OBJC_MAIN}
        echo "export CPPFLAGS=\"${CPPFLAGS}\"" >> ${BUILD_OBJC_MAIN}
        echo "export CFLAGS=\"${CFLAGS}\"" >> ${BUILD_OBJC_MAIN}
        echo "${COMPILE} >> ${LOG} 2>&1 || ${COMPILE}" >> ${BUILD_OBJC_MAIN}
        update_and_chmod 755 ${BUILD_OBJC_MAIN} build_objc_main
    }
    
    update_build_prog() {
        BUILD_PROG_MAIN=build_prog_main.tmp
        BUILD_PROG_ASAN=build_prog_asan.tmp
        BUILD_PROG_COV=build_prog_cov.tmp
        BUILD_PROG_DEBUG=build_prog_debug.tmp
        mkdir -p .build
    
        LINK="\${LD} \${LDFLAGS} \${OBJECTS} \${LIBS} \${PROG_LDADD}"
        LINK="$LINK -o \"\$1\""
    
        echo "#!/bin/sh" >> ${BUILD_PROG_ASAN}
        echo "# generated by configure" >> ${BUILD_PROG_ASAN}
        echo "LOG=\".build/\$1.asan.log\"" >> ${BUILD_PROG_ASAN}
        echo "export LD=\"${LD}\"" >> ${BUILD_PROG_ASAN}
        echo "LDFLAGS=\"${LDFLAGS_ASAN}\"" >> ${BUILD_PROG_ASAN}
        echo "OBJECTS=\"${OBJECTS_ASAN}\"" >> ${BUILD_PROG_ASAN}
        echo "LIBS=\"${LIBS_ASAN}\"" >> ${BUILD_PROG_ASAN}
        echo "PROG_LDADD=\"${PROG_LDADD}\"" >> ${BUILD_PROG_ASAN}
        echo >> ${BUILD_PROG_ASAN}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_PROG_ASAN}
        update_and_chmod 755 ${BUILD_PROG_ASAN} build_prog_asan
    
        echo "#!/bin/sh" >> ${BUILD_PROG_COV}
        echo "# generated by configure" >> ${BUILD_PROG_COV}
        echo "LOG=\".build/\$1.cov.log\"" >> ${BUILD_PROG_COV}
        echo "export LD=\"${LD}\"" >> ${BUILD_PROG_COV}
        echo "LDFLAGS=\"${LDFLAGS_COV}\"" >> ${BUILD_PROG_COV}
        echo "OBJECTS=\"${OBJECTS_COV}\"" >> ${BUILD_PROG_COV}
        echo "LIBS=\"${LIBS_COV}\"" >> ${BUILD_PROG_COV}
        echo "PROG_LDADD=\"${PROG_LDADD}\"" >> ${BUILD_PROG_COV}
        echo >> ${BUILD_PROG_COV}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_PROG_COV}
        update_and_chmod 755 ${BUILD_PROG_COV} build_prog_cov
    
        echo "#!/bin/sh" >> ${BUILD_PROG_DEBUG}
        echo "# generated by configure" >> ${BUILD_PROG_DEBUG}
        echo "LOG=\".build/\$1.debug.log\"" >> ${BUILD_PROG_DEBUG}
        echo "export LD=\"${LD}\"" >> ${BUILD_PROG_DEBUG}
        echo "LDFLAGS=\"${LDFLAGS_DEBUG}\"" >> ${BUILD_PROG_DEBUG}
        echo "OBJECTS=\"${OBJECTS_DEBUG}\"" >> ${BUILD_PROG_DEBUG}
        echo "LIBS=\"${LIBS_DEBUG}\"" >> ${BUILD_PROG_DEBUG}
        echo "PROG_LDADD=\"${PROG_LDADD}\"" >> ${BUILD_PROG_DEBUG}
        echo >> ${BUILD_PROG_DEBUG}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_PROG_DEBUG}
        update_and_chmod 755 ${BUILD_PROG_DEBUG} build_prog_debug
    
        echo "#!/bin/sh" >> ${BUILD_PROG_MAIN}
        echo "# generated by configure" >> ${BUILD_PROG_MAIN}
        echo "LOG=\".build/\$1.main.log\"" >> ${BUILD_PROG_MAIN}
        echo "export LD=\"${LD}\"" >> ${BUILD_PROG_MAIN}
        echo "LDFLAGS=\"${LDFLAGS}\"" >> ${BUILD_PROG_MAIN}
        echo "OBJECTS=\"${OBJECTS}\"" >> ${BUILD_PROG_MAIN}
        echo "LIBS=\"${LIBS}\"" >> ${BUILD_PROG_MAIN}
        echo "PROG_LDADD=\"${PROG_LDADD}\"" >> ${BUILD_PROG_MAIN}
        echo >> ${BUILD_PROG_MAIN}
        echo "$LINK > \"\$LOG\" 2>&1 || $LINK" >> ${BUILD_PROG_MAIN}
        update_and_chmod 755 ${BUILD_PROG_MAIN} build_prog_main
    }
    
    update_file() {
        if ! cmp "$1" "$2" >/dev/null 2>&1; then
            mv "$1" "$2"
            echo "-> ${PWD}/$2"
        else
            rm "$1"
        fi
    }
    
    update_config_mk() {
        if ! cmp "${CONFIG_MK}" config.mk >/dev/null 2>&1; then
            mv "${CONFIG_MK}" config.mk
            echo "-> ${PWD}/config.mk"
        else
            rm "${CONFIG_MK}"
        fi
    }
    
    update_config_sh() {
        if ! cmp "${CONFIG_SH}" config.sh >/dev/null 2>&1; then
            mv "${CONFIG_SH}" config.sh
            echo "-> ${PWD}/config.sh"
        else
            rm "${CONFIG_SH}"
        fi
    }
    
    update_makefile() {
        if [ "x${BUILD_TOP}" != "x${SRC_TOP}" ]; then
    	if ! [ -h Makefile ]; then
                echo "-> ${PWD}/Makefile"
                ln -sf "${SRC_DIR}/Makefile" ./
    	fi
    	if [ -f "${SRC_DIR}/sources.mk" ] && ! [ -h sources.mk ]; then
                echo "-> ${PWD}/sources.mk"
                ln -sf "${SRC_DIR}/sources.mk" ./
    	fi
        fi
    }
    
    update_sources_mk() {
        if ! cmp "${SOURCES_MK}" sources.mk >/dev/null 2>&1; then
            mv "${SOURCES_MK}" sources.mk
            echo "-> ${PWD}/sources.mk"
        else
            rm "${SOURCES_MK}"
        fi
    }
    
    update_sources_sh() {
        if ! cmp "${SOURCES_SH}" sources.sh >/dev/null 2>&1; then
            mv "${SOURCES_SH}" sources.sh
            echo "-> ${PWD}/sources.sh"
        else
            rm "${SOURCES_SH}"
        fi
    }
    
    CONFIG_MK=config.mk
    CONFIG_MK=".config.mk.tmp"
    echo "# config.mk generated by configure" > ${CONFIG_MK}
    CONFIG_SH=config.sh
    CONFIG_SH=".config.sh.tmp"
    echo "# config.sh generated by configure" > ${CONFIG_SH}
    
    SOURCES_MK=sources.mk
    SOURCES_MK=".sources.mk.tmp"
    SOURCES_SH=sources.sh
    SOURCES_SH=".sources.sh.tmp"
    
    VER=0.1.16-git
    echo "VER = $VER" >> ${CONFIG_MK}
    
    echo "BUILD_TOP = $BUILD_TOP" >> ${CONFIG_MK}
    
    export SRC_DIR="${SRC_TOP}/${DIR}"
    echo "SRC_TOP = $SRC_TOP" >> ${CONFIG_MK}
    echo "SRC_DIR = $SRC_DIR" >> ${CONFIG_MK}
    
    ENV_CPPFLAGS="$CPPFLAGS"
    ENV_CFLAGS="$CFLAGS"
    ENV_CXXFLAGS="$CXXFLAGS"
    ENV_LDFLAGS="$LDFLAGS"
    ENV_LIBS="$LIBS"
    
    if [ "x$CC" = "x" ]; then
        if which cc >/dev/null 2>&1; then
            CC=cc
        elif which gcc >/dev/null 2>&1; then
            CC=gcc
        fi
    fi
    echo "CC = $CC" >> ${CONFIG_MK}
    
    CC_TARGET=$(LC_ALL=C cc -v 2>&1 | grep 'Target: ' | cut -c 9-)
    echo "CC_TARGET = $CC_TARGET" >> ${CONFIG_MK}
    
    if [ "x$CXX" = "x" ]; then
        if which c++ >/dev/null 2>&1; then
            CXX=c++
        elif which g++ >/dev/null 2>&1; then
            CXX=g++
        fi
    fi
    echo "CXX = $CXX" >> ${CONFIG_MK}
    
    if [ "x$host" != "x" ]; then
        echo "host = $host" >> ${CONFIG_MK}
        echo "CFLAGS_HOST = --host $host" >> ${CONFIG_MK}
    else
        echo "CFLAGS_HOST =" >> ${CONFIG_MK}
    fi
    if [ "x$target" != "x" ]; then
        echo "target = $target" >> ${CONFIG_MK}
        echo "CFLAGS_TARGET = --target $target" >> ${CONFIG_MK}
    else
        echo "CFLAGS_TARGET =" >> ${CONFIG_MK}
    fi
    
    if [ "x$LD" = "x" ]; then
        if which ld >/dev/null 2>&1; then
            LD=ld
        fi
    fi
    echo "LD = $LD" >> ${CONFIG_MK}
    
    if [ "x$AR" != "x" ]; then
        echo "AR = $AR" >> ${CONFIG_MK}
    fi
    if [ "x$RANLIB" != "x" ]; then
        echo "RANLIB = $RANLIB" >> ${CONFIG_MK}
    fi
    
    HAVE_GCOV=false
    if [ "x$GCOV" = "xfalse" ]; then
        HAVE_GCOV=false
    else
        if [ "x$GCOV" = "x" ]; then
            if which gcov >/dev/null 2>&1; then
    	    GCOV=gcov
                HAVE_GCOV=true
            elif which egcov >/dev/null 2>&1; then
    	    GCOV=egcov
                HAVE_GCOV=true
            fi
        else
            HAVE_GCOV=true
        fi
    fi
    echo "HAVE_GCOV = $HAVE_GCOV" >> ${CONFIG_MK}
    if ${HAVE_GCOV}; then
        echo "GCOV = $GCOV" >> ${CONFIG_MK}
    fi
    
    if [ "x$GDB" = "x" ]; then
        if which egdb 2>/dev/null; then
            GDB=egdb
        else
            GDB=gdb
        fi
    fi
    echo "GDB = $GDB" >> ${CONFIG_MK}
    
    if [ "x$GMAKE" = "x" ]; then
        if which gmake >/dev/null 2>&1; then
            GMAKE=gmake
        else
            GMAKE=make
        fi
    fi
    echo "GMAKE = $GMAKE" >> ${CONFIG_MK}
    
    if [ "x$INSTALL" = "x" ]; then
        if which install >/dev/null 2>&1; then
            INSTALL=install
        fi
    fi
    echo "INSTALL = $INSTALL" >> ${CONFIG_MK}
    
    if [ "x$OBJC" = "x" ]; then
        if test -x "$(which clang)"; then
            OBJC="$(which clang)"
        else
            OBJC=clang
        fi
    fi
    echo "OBJC = $OBJC" >> ${CONFIG_MK}
    
    : ${DESTDIR:=}
    echo "DESTDIR ?= ${DESTDIR}" >> ${CONFIG_MK}
    
    : ${PREFIX:=/usr/local}
    echo "PREFIX = $PREFIX" >> ${CONFIG_MK}
    echo "PREFIX=$PREFIX" >> ${CONFIG_SH}
    echo "prefix ?= ${PREFIX}" >> ${CONFIG_MK}
    echo "prefix=${PREFIX}" >> ${CONFIG_SH}
    
    if [ "x$DESTDIR" != "x" ]; then
        mkdir -p "$DESTDIR"
        if [ "x$OWNER" = "x" ]; then
            OWNER="$(ls -ld "$DESTDIR" | tr -s ' ' | cut -d ' ' -f 3)"
        fi
        if [ "x$GROUP" = "x" ]; then
            GROUP="$(ls -ld "$DESTDIR" | tr -s ' ' | cut -d ' ' -f 4)"
        fi
    else
        if [ "x$OWNER" = "x" ]; then
            OWNER="$(ls -ld "$PREFIX" | tr -s ' ' | cut -d ' ' -f 3)"
        fi
        if [ "x$GROUP" = "x" ]; then
            GROUP="$(ls -ld "$PREFIX" | tr -s ' ' | cut -d ' ' -f 4)"
        fi
    fi
    echo "OWNER = $OWNER" >> ${CONFIG_MK}
    echo "GROUP = $GROUP" >> ${CONFIG_MK}
    
    if [ "x$BINDIR" = "x" ]; then
        BINDIR="${PREFIX}/bin"
    fi
    echo "BINDIR = $BINDIR" >> ${CONFIG_MK}
    
    if [ "x$LIBDIR" = "x" ]; then
        LIBDIR="${PREFIX}/lib"
    fi
    echo "LIBDIR = $LIBDIR" >> ${CONFIG_MK}
    
    EXPORT_DYNAMIC="--export-dynamic"
    case "$(uname -s)" in
        CYGWIN*|MINGW*|MSYS*|Windows)
            SHARED_FLAGS="-shared"
            SHARED_EXT="dll"
            SHARED_MAJOR="-$VER_MAJOR.$SHARED_EXT"
            SHARED_MINOR="-$VER_MAJOR.$VER_MINOR.$SHARED_EXT"
            SHARED_PATCH="-$VER_MAJOR.$VER_MINOR.$VER_PATCH.$SHARED_EXT"
            LIB_SUFFIX="dll"
            LIB_LINK_SUFFIX="dll"
            IMPLIB="--out-implib \${LIB_BASE}.dll.a"
            LDADD=""
            PROG_LDADD="$LDADD"
            ;;
        Darwin)
            SHARED_FLAGS="-dylib -install_name @rpath/\${LIB_BASE}.\${VER_MAJOR}.dylib"
            SHARED_EXT="dylib"
            SHARED_MAJOR=".$VER_MAJOR.$SHARED_EXT"
            SHARED_MINOR=".$VER_MAJOR.$VER_MINOR.$SHARED_EXT"
            SHARED_PATCH=".$VER_MAJOR.$VER_MINOR.$VER_PATCH.$SHARED_EXT"
            LIB_SUFFIX="\${VER_MAJOR}.dylib"
            LIB_LINK_SUFFIX="dylib"
            MACOS_SDK=$(xcrun --show-sdk-path 2>/dev/null || echo "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk")
            LDFLAGS="$LDFLAGS -L${MACOS_SDK}/usr/lib"
            LDFLAGS="$LDFLAGS -F${MACOS_SDK}/System/Library/Frameworks"
            LDADD="-lSystem -headerpad_max_install_names"
            LIB_LDADD="$LDADD"
            PROG_LDADD="$LDADD"
            EXPORT_DYNAMIC="-export_dynamic"
            ;;
        FreeBSD)
            SHARED_FLAGS="-shared"
            SHARED_EXT="so"
            SHARED_MAJOR=".$SHARED_EXT.$VER_MAJOR"
            SHARED_MINOR="$SHARED_MAJOR.$VER_MINOR"
            SHARED_PATCH="$SHARED_MINOR.$VER_PATCH"
            LIB_SUFFIX="so.\${VER_MAJOR}"
            LIB_LINK_SUFFIX="so"
            LDFLAGS="$LDFLAGS -L/usr/lib"
            LDADD="-lc"
            LIB_LDADD="/usr/lib/crti.o /usr/lib/crtbeginS.o $LDADD /usr/lib/crtendS.o /usr/lib/crtn.o"
            PROG_LDADD="/usr/lib/crt1.o"
            PROG_LDADD="$PROG_LDADD /usr/lib/crti.o"
            PROG_LDADD="$PROG_LDADD /usr/lib/crtbegin.o"
            PROG_LDADD="$PROG_LDADD -e _start"
            PROG_LDADD="$PROG_LDADD --dynamic-linker=/usr/libexec/ld-elf.so.1"
            PROG_LDADD="$PROG_LDADD $LDADD"
            PROG_LDADD="$PROG_LDADD /usr/lib/crtend.o"
            PROG_LDADD="$PROG_LDADD /usr/lib/crtn.o"
            ;;
        NetBSD)
            SHARED_FLAGS="-shared"
            SHARED_EXT="so"
            SHARED_MAJOR=".$SHARED_EXT.$VER_MAJOR"
            SHARED_MINOR="$SHARED_MAJOR.$VER_MINOR"
            SHARED_PATCH="$SHARED_MINOR.$VER_PATCH"
            LIB_SUFFIX="so.\${VER_MAJOR}.\${VER_MINOR}"
            LIB_LINK_SUFFIX="so"
            LDFLAGS="$LDFLAGS -L/usr/lib"
            LDADD="-lc"
            LIB_LDADD="/usr/lib/crti.o /usr/lib/crtbeginS.o $LDADD /usr/lib/crtendS.o /usr/lib/crtn.o"
            PROG_LDADD="/usr/lib/crt0.o /usr/lib/crti.o /usr/lib/crtbegin.o -e __start --dynamic-linker=/usr/libexec/ld.elf_so $LDADD /usr/lib/crtend.o /usr/lib/crtn.o"
            ;;
        OpenBSD)
            SHARED_FLAGS="-shared"
            SHARED_EXT="so"
            SHARED_MAJOR=".$SHARED_EXT.$VER_MAJOR"
            SHARED_MINOR="$SHARED_MAJOR.$VER_MINOR"
            SHARED_PATCH="$SHARED_MINOR.$VER_PATCH"
            LIB_SUFFIX="so.\${VER_MAJOR}.\${VER_MINOR}"
            LIB_LINK_SUFFIX="so"
            LDFLAGS="$LDFLAGS -L/usr/lib"
            LDADD="-lc"
            LIB_LDADD="/usr/lib/crtbeginS.o $LDADD /usr/lib/crtendS.o"
            PROG_LDADD="/usr/lib/crt0.o /usr/lib/crtbegin.o -e __start --dynamic-linker=/usr/libexec/ld.so $LDADD /usr/lib/crtend.o"
            ;;
        Linux)
            SHARED_FLAGS="-shared -soname \${LIB_BASE}.so.\${VER_MAJOR}"
            SHARED_EXT="so"
            SHARED_MAJOR=".$SHARED_EXT.$VER_MAJOR"
            SHARED_MINOR="$SHARED_MAJOR.$VER_MINOR"
            SHARED_PATCH="$SHARED_MINOR.$VER_PATCH"
            LIB_SUFFIX="so.\${VER_MAJOR}.\${VER_MINOR}.\${VER_PATCH}"
            LIB_LINK_SUFFIX="so"
            LIBGCC=$(${CC} -print-libgcc-file-name)
            LDADD="$LIBGCC -lc"
            CRT1=$(${CC} -print-file-name=crt1.o)
            CRTI=$(${CC} -print-file-name=crti.o)
            CRTBEGIN=$(${CC} -print-file-name=crtbegin.o)
            CRTBEGINS=$(${CC} -print-file-name=crtbeginS.o)
            CRTEND=$(${CC} -print-file-name=crtend.o)
            CRTENDS=$(${CC} -print-file-name=crtendS.o)
            CRTN=$(${CC} -print-file-name=crtn.o)
            LDSO=$(${CC} -print-file-name=ld-linux-aarch64.so.1)
            if [ ! -f "$LDSO" ]; then
                LDSO=$(${CC} -print-file-name=ld-linux-x86-64.so.2)
            fi
            if [ ! -f "$LDSO" ]; then
                LDSO=$(${CC} -print-file-name=ld-linux.so.2)
            fi
            LIB_LDADD="$CRTI $CRTBEGINS $LDADD $CRTENDS $CRTN"
            PROG_LDADD="$CRT1 $CRTI $CRTBEGIN -e _start --dynamic-linker=$LDSO $LDADD $CRTEND $CRTN"
            ;;
        *)
            echo "Unsupported OS : $(uname -s)" >&2
            exit 1;
    esac
    {
        echo "SHARED_FLAGS = ${SHARED_FLAGS}" >> ${CONFIG_MK}
        echo "SHARED_EXT = ${SHARED_EXT}" >> ${CONFIG_MK}
        echo "LIB_SUFFIX = ${LIB_SUFFIX}" >> ${CONFIG_MK}
        echo "LIB_LINK_SUFFIX = ${LIB_LINK_SUFFIX}" >> ${CONFIG_MK}
        echo "IMPLIB = ${IMPLIB}"
    } >> ${CONFIG_MK}
    
    {
        echo "CLEANFILES = *.a *.gcno *.la .libs *.o *.so *.so.* *.dylib"
        echo "CLEANFILES_COV = *.css *.gcda *.html"
        echo "CLEANFILES += \${CLEANFILES_COV}"
        echo "DISTCLEANFILES = .build \${CLEANFILES} config.mk"
        echo
        echo "clean::"
        echo "	rm -rf \${CLEANFILES}"
        echo
        echo "clean_cov::"
        echo "	rm -rf \${CLEANFILES_COV}"
        echo
        echo "distclean::"
        echo "	rm -rf \${DISTCLEANFILES}"
        echo
        echo ".PHONY: clean clean_cov distclean"
        echo
    } >> ${CONFIG_MK}
    
    config_no_undefined