# This file contains the functions common to glibc and eglibc

# Extract the C library tarball(s)
do_libc_extract() {
    local addon

    # Extract the main tarball
    CT_Extract "${CT_LIBC}-${CT_LIBC_VERSION}"
    CT_Pushd "${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
    CT_Patch nochdir "${CT_LIBC}" "${CT_LIBC_VERSION}"

    # Extract the add-opns
    for addon in $(do_libc_add_ons_list " "); do
        # If the addon was bundled with the main archive, we do not
        # need to extract it. Worse, if we were to try to extract
        # it, we'd get an error.
        if [ -d "${addon}" ]; then
            CT_DoLog DEBUG "Add-on '${addon}' already present, skipping extraction"
            continue
        fi

        CT_Extract nochdir "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}"

        CT_TestAndAbort "Error in add-on '${addon}': both short and long names in tarball" \
            -d "${addon}" -a -d "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}"

        # Some addons have the 'long' name, while others have the
        # 'short' name, but patches are non-uniformly built with
        # either the 'long' or 'short' name, whatever the addons name
        # but we prefer the 'short' name and avoid duplicates.
        if [ -d "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}" ]; then
            CT_DoExecLog FILE mv "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}" "${addon}"
        fi

        CT_DoExecLog FILE ln -s "${addon}" "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}"

        CT_Patch nochdir "${CT_LIBC}" "${addon}-${CT_LIBC_VERSION}"

        # Remove the long name since it can confuse configure scripts to run
        # the same source twice.
        rm "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}"
    done

    # The configure files may be older than the configure.in files
    # if using a snapshot (or even some tarballs). Fake them being
    # up to date.
    find . -type f -name configure -exec touch {} \; 2>&1 |CT_DoLog ALL

    CT_Popd

    if [ "${CT_LIBC_LOCALES}" = "y" ]; then
        do_libc_locales_extract
    fi
}

# Build and install headers and start files
do_libc_start_files() {
    # Start files and Headers should be configured the same way as the
    # final libc, but built and installed differently.
    do_libc_backend libc_mode=startfiles
}

# This function builds and install the full C library
do_libc() {
    do_libc_backend libc_mode=final
}

# This backend builds the C library once for each multilib
# variant the compiler gives us
# Usage: do_libc_backend param=value [...]
#   Parameter           : Definition                            : Type      : Default
#   libc_mode           : 'startfiles' or 'final'               : string    : (none)
do_libc_backend() {
    local libc_mode
    local -a multilibs
    local multilib
    local multi_dir
    local multi_flags
    local extra_dir
    local libc_headers libc_startfiles libc_full
    local hdr
    local arg

    for arg in "$@"; do
        eval "${arg// /\\ }"
    done

    case "${libc_mode}" in
        startfiles)
            CT_DoStep INFO "Installing C library headers & start files"
            hdr=y
            libc_startfiles=y
            libc_full=
            ;;
        final)
            CT_DoStep INFO "Installing C library"
            hdr=
            libc_startfiles=
            libc_full=y
            ;;
        *)  CT_Abort "Unsupported (or unset) libc_mode='${libc_mode}'";;
    esac

    # If gcc is not configured for multilib, it still prints
    # a single line for the default settings
    multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null) )
    for multilib in "${multilibs[@]}"; do
        multi_dir="${multilib%%;*}"
        if [ "${multi_dir}" != "." ]; then
            CT_DoStep INFO "Building for multilib subdir='${multi_dir}'"

            extra_flags="$( echo "${multilib#*;}"       \
                            |${sed} -r -e 's/@/ -/g;'   \
                          )"
            extra_dir="/${multi_dir}"

            # glibc install its files in ${extra_dir}/{usr/,}lib
            # while gcc expects them in {,usr/}lib/${extra_dir}.
            # Prepare some symlinks so glibc installs in fact in
            # the proper place
            # We do it in the start-files step, so it is not needed
            # to do it in the final step, as the symlinks will
            # already exist
            if [ "${libc_mode}" = "startfiles" ]; then
                CT_Pushd "${CT_SYSROOT_DIR}"
                CT_DoExecLog ALL mkdir -p "lib/${multi_dir}"        \
                                          "usr/lib/${multi_dir}"    \
                                          "${multi_dir}"            \
                                          "${multi_dir}/usr"
                CT_DoExecLog ALL ln -sf "../lib/${multi_dir}" "${multi_dir}/lib"
                CT_DoExecLog ALL ln -sf "../../usr/lib/${multi_dir}" "${multi_dir}/usr/lib"
                CT_Popd
            fi
            libc_headers=
        else
            extra_dir=
            extra_flags=
            libc_headers="${hdr}"
        fi

        CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-${libc_mode}${extra_dir//\//_}"

        do_libc_backend_once extra_dir="${extra_dir}"               \
                             extra_flags="${extra_flags}"           \
                             libc_headers="${libc_headers}"         \
                             libc_startfiles="${libc_startfiles}"   \
                             libc_full="${libc_full}"

        CT_Popd

        if [ "${multi_dir}" != "." ]; then
            if [ "${libc_mode}" = "final" ]; then
                CT_DoLog EXTRA "Fixing up multilib location"

                # rewrite the library multiplexers
                for d in "lib/${multi_dir}" "usr/lib/${multi_dir}"; do
                    for l in libc libpthread libgcc_s; do
                        if [    -f "${CT_SYSROOT_DIR}/${d}/${l}.so"    \
                             -a ! -L ${CT_SYSROOT_DIR}/${d}/${l}.so    ]
                        then
                            CT_DoExecLog DEBUG ${sed} -r -i                                 \
                                                      -e "s:/lib/:/lib/${multi_dir}/:g;"    \
                                                      "${CT_SYSROOT_DIR}/${d}/${l}.so"
                        fi
                    done
                done
                # Remove the multi_dir now it is no longer useful
                CT_DoExecLog DEBUG rm -rf "${CT_SYSROOT_DIR}/${multi_dir}"
            fi # libc_mode == final

            CT_EndStep
        fi
    done

    CT_EndStep
}

# This backend builds the C library once
# Usage: do_libc_backend_once param=value [...]
#   Parameter           : Definition                            : Type      : Default
#   libc_headers        : Build libc headers                    : bool      : n
#   libc_startfiles     : Build libc start-files                : bool      : n
#   libc_full           : Build full libc                       : bool      : n
#   extra_flags         : Extra CFLAGS to use (for multilib)    : string    : (empty)
#   extra_dir           : Extra subdir for multilib             : string    : (empty)
do_libc_backend_once() {
    local libc_headers
    local libc_startfiles
    local libc_full
    local extra_flags
    local extra_dir
    local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
    local extra_cc_args
    local -a extra_config
    local -a extra_make_args
    local glibc_cflags
    local float_extra
    local endian_extra
    local arg

    for arg in "$@"; do
        eval "${arg// /\\ }"
    done

    CT_DoLog EXTRA "Configuring C library"

    case "${CT_LIBC}" in
        eglibc)
            if [ "${CT_EGLIBC_CUSTOM_CONFIG}" = "y" ]; then
                CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/eglibc.config" option-groups.config
            fi
            if [ "${CT_EGLIBC_OPT_SIZE}" = "y" ]; then
                OPTIMIZE=-Os
            else
                OPTIMIZE=-O2
            fi
            # always include rpc, the user can still override it with TI-RPC
            extra_config+=( --enable-obsolete-rpc )
            ;;
        glibc)
            # glibc can't be built without -O2 (reference needed!)
            OPTIMIZE=-O2
            # Also, if those two are missing, iconv build breaks
            extra_config+=( --disable-debug --disable-sanity-checks )
            ;;
    esac

    # Add some default glibc config options if not given by user.
    # We don't need to be conditional on wether the user did set different
    # values, as they CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY is passed after
    # extra_config

    extra_config+=("$(do_libc_min_kernel_config)")

    case "${CT_THREADS}" in
        nptl)           extra_config+=("--with-__thread" "--with-tls");;
        linuxthreads)   extra_config+=("--with-__thread" "--without-tls" "--without-nptl");;
        none)           extra_config+=("--without-__thread" "--without-nptl")
                        case "${CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY[*]}" in
                            *-tls*) ;;
                            *) extra_config+=("--without-tls");;
                        esac
                        ;;
    esac

    case "${CT_SHARED_LIBS}" in
        y) extra_config+=("--enable-shared");;
        *) extra_config+=("--disable-shared");;
    esac

    float_extra="$( echo "${extra_flags}"       \
                    |${sed} -r -e '/^(.*[[:space:]])?-m(hard|soft)-float([[:space:]].*)?$/!d;'  \
                               -e 's//\2/;'     \
                  )"
    case "${float_extra}" in
        hard)   extra_config+=("--with-fp");;
        soft)   extra_config+=("--without-fp");;
        "")
            case "${CT_ARCH_FLOAT}" in
                hard|softfp)    extra_config+=("--with-fp");;
                soft)           extra_config+=("--without-fp");;
            esac
            ;;
    esac

    if [ "${CT_LIBC_DISABLE_VERSIONING}" = "y" ]; then
        extra_config+=("--disable-versioning")
    fi

    if [ "${CT_LIBC_OLDEST_ABI}" != "" ]; then
        extra_config+=("--enable-oldest-abi=${CT_LIBC_OLDEST_ABI}")
    fi

    case "$(do_libc_add_ons_list ,)" in
        "") extra_config+=("--enable-add-ons=no");;
        *)  extra_config+=("--enable-add-ons=$(do_libc_add_ons_list ,)");;
    esac

    extra_config+=("--with-pkgversion=${CT_PKGVERSION}")
    [ -n "${CT_TOOLCHAIN_BUGURL}" ] && extra_config+=("--with-bugurl=${CT_TOOLCHAIN_BUGURL}")

    # Extract the endianness options if any
    # This should cover all possible endianness options
    # in gcc, but it is prone to bit-rot... :-(
    endian_extra="$( echo "${extra_flags}"      \
                     |${sed} -r -e '/^(.*[[:space:]])?-(E[BL]|m((big|little)(-endian)?|e?[bl]))([[:space:]].*)?$/!d;' \
                                -e 's//\2/;'    \
                   )"
    case "${endian_extra}" in
        EB|mbig-endian|mbig|meb|mb)
            extra_cc_args="${extra_cc_args} ${endian_extra}"
            ;;
        EL|mlittle-endian|mlittle|mel|ml)
            extra_cc_args="${extra_cc_args} ${endian_extra}"
            ;;
        "") extra_cc_args="${extra_cc_args} ${CT_ARCH_ENDIAN_OPT}"
            ;;
    esac

    touch config.cache
    if [ "${CT_LIBC_GLIBC_FORCE_UNWIND}" = "y" ]; then
        echo "libc_cv_forced_unwind=yes" >>config.cache
        echo "libc_cv_c_cleanup=yes" >>config.cache
    fi

    # Pre-seed the configparms file with values from the config option
    printf "%s\n" "${CT_LIBC_GLIBC_CONFIGPARMS}" > configparms

    cross_cc=$(CT_Which "${CT_TARGET}-gcc")
    extra_cc_args+=" ${extra_flags}"

    case "${CT_LIBC_ENABLE_FORTIFIED_BUILD}" in
        y)  ;;
        *)  glibc_cflags+=" -U_FORTIFY_SOURCE";;
    esac
    glibc_cflags+=" ${CT_TARGET_CFLAGS} ${OPTIMIZE} ${CT_LIBC_GLIBC_EXTRA_CFLAGS}"

    # ./configure is mislead by our tools override wrapper for bash
    # so just tell it where the real bash is _on_the_target_!
    # Notes:
    # - ${ac_cv_path_BASH_SHELL} is only used to set BASH_SHELL
    # - ${BASH_SHELL}            is only used to set BASH
    # - ${BASH}                  is only used to set the shebang
    #                            in two scripts to run on the target
    # So we can safely bypass bash detection at compile time.
    # Should this change in a future eglibc release, we'd better
    # directly mangle the generated scripts _after_ they get built,
    # or even after they get installed...
    echo "ac_cv_path_BASH_SHELL=/bin/bash" >>config.cache

    # Configure with --prefix the way we want it on the target...
    # There are a whole lot of settings here.  You'll probably want
    # to read up on what they all mean, and customize a bit, possibly by setting GLIBC_EXTRA_CONFIG_ARRAY
    # Compare these options with the ones used when installing the glibc headers above - they're different.
    # Adding "--without-gd" option to avoid error "memusagestat.c:36:16: gd.h: No such file or directory"
    # See also http://sources.redhat.com/ml/libc-alpha/2000-07/msg00024.html.
    # Set BUILD_CC, or we won't be able to build datafiles
    # Run explicitly through CONFIG_SHELL, or the build breaks badly (loop-of-death)
    # when the shell is not bash... Sigh... :-(

    CT_DoLog DEBUG "Using gcc for target    : '${cross_cc}'"
    CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'"
    CT_DoLog DEBUG "Extra config args passed: '${extra_config[*]}'"
    CT_DoLog DEBUG "Extra CC args passed    : '${glibc_cflags}'"
    CT_DoLog DEBUG "Extra flags (multilib)  : '${extra_flags}'"

    CT_DoExecLog CFG                                                \
    BUILD_CC="${CT_BUILD}-gcc"                                      \
    CFLAGS="${glibc_cflags}"                                        \
    CC="${CT_TARGET}-gcc ${CT_LIBC_EXTRA_CC_ARGS} ${extra_cc_args}" \
    AR=${CT_TARGET}-ar                                              \
    RANLIB=${CT_TARGET}-ranlib                                      \
    "${CONFIG_SHELL}"                                               \
    "${src_dir}/configure"                                          \
        --prefix=/usr                                               \
        --build=${CT_BUILD}                                         \
        --host=${CT_TARGET}                                         \
        --cache-file="$(pwd)/config.cache"                          \
        --without-cvs                                               \
        --disable-profile                                           \
        --without-gd                                                \
        --with-headers="${CT_HEADERS_DIR}"                          \
        "${extra_config[@]}"                                        \
        "${CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY[@]}"

    # build hacks
    case "${CT_ARCH},${CT_ARCH_CPU}" in
        powerpc,8??)
            # http://sourceware.org/ml/crossgcc/2008-10/msg00068.html
            CT_DoLog DEBUG "Activating support for memset on broken ppc-8xx (CPU15 erratum)"
            extra_make_args+=( ASFLAGS="-DBROKEN_PPC_8xx_CPU15" )
            ;;
    esac

    if [ "${libc_headers}" = "y" ]; then
        CT_DoLog EXTRA "Installing C library headers"

        # use the 'install-headers' makefile target to install the
        # headers
        CT_DoExecLog ALL make ${JOBSFLAGS}                          \
                         install_root=${CT_SYSROOT_DIR}${extra_dir} \
                         install-bootstrap-headers=yes              \
                         "${extra_make_args[@]}"                    \
                         install-headers

        # For glibc, a few headers need to be manually installed
        if [ "${CT_LIBC}" = "glibc" ]; then
            # Two headers -- stubs.h and features.h -- aren't installed by install-headers,
            # so do them by hand.  We can tolerate an empty stubs.h for the moment.
            # See e.g. http://gcc.gnu.org/ml/gcc/2002-01/msg00900.html
            mkdir -p "${CT_HEADERS_DIR}/gnu"
            CT_DoExecLog ALL touch "${CT_HEADERS_DIR}/gnu/stubs.h"
            CT_DoExecLog ALL cp -v "${CT_SRC_DIR}/glibc-${CT_LIBC_VERSION}/include/features.h"  \
                                   "${CT_HEADERS_DIR}/features.h"

            # Building the bootstrap gcc requires either setting inhibit_libc, or
            # having a copy of stdio_lim.h... see
            # http://sources.redhat.com/ml/libc-alpha/2003-11/msg00045.html
            CT_DoExecLog ALL cp -v bits/stdio_lim.h "${CT_HEADERS_DIR}/bits/stdio_lim.h"

            # Following error building gcc-4.0.0's gcj:
            #  error: bits/syscall.h: No such file or directory
            # solved by following copy; see http://sourceware.org/ml/crossgcc/2005-05/msg00168.html
            # but it breaks arm, see http://sourceware.org/ml/crossgcc/2006-01/msg00091.html
            # Of course, only copy it if it does not already exist
            case "${CT_ARCH}" in
                arm)    ;;
                *)  if [ -f "${CT_HEADERS_DIR}/bits/syscall.h" ]; then
                        CT_DoLog ALL "Not over-writing existing bits/syscall.h"
                    elif [ -f "misc/bits/syscall.h" ]; then
                        CT_DoExecLog ALL cp -v "misc/bits/syscall.h"            \
                                               "${CT_HEADERS_DIR}/bits/syscall.h"
                    else
                        # "Old" glibces do not have the above file,
                        # but provide this one:
                        CT_DoExecLog ALL cp -v "misc/syscall-list.h"            \
                                               "${CT_HEADERS_DIR}/bits/syscall.h"
                    fi
                    ;;
            esac
        fi
    fi # libc_headers == y

    if [ "${libc_startfiles}" = "y" ]; then
        if [ "${CT_THREADS}" = "nptl" ]; then
            CT_DoLog EXTRA "Installing C library start files"

            # there are a few object files needed to link shared libraries,
            # which we build and install by hand
            CT_DoExecLog ALL mkdir -p "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"
            CT_DoExecLog ALL make ${JOBSFLAGS}  \
                        "${extra_make_args[@]}" \
                        csu/subdir_lib
            CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o    \
                                "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"

            # Finally, 'libgcc_s.so' requires a 'libc.so' to link against.
            # However, since we will never actually execute its code,
            # it doesn't matter what it contains.  So, treating '/dev/null'
            # as a C source file, we produce a dummy 'libc.so' in one step
            CT_DoExecLog ALL "${cross_cc}" -nostdlib        \
                                           -nostartfiles    \
                                           -shared          \
                                           -x c /dev/null   \
                                           -o "${CT_SYSROOT_DIR}${extra_dir}/usr/lib/libc.so"
        fi # threads == nptl
    fi # libc_headers == y

    if [ "${libc_full}" = "y" ]; then
        CT_DoLog EXTRA "Building C library"
        CT_DoExecLog ALL make ${JOBSFLAGS}              \
                              "${extra_make_args[@]}"   \
                              all

        CT_DoLog EXTRA "Installing C library"
        CT_DoExecLog ALL make ${JOBSFLAGS}                                  \
                              "${extra_make_args[@]}"                       \
                              install_root="${CT_SYSROOT_DIR}${extra_dir}"  \
                              install

        if [ "${CT_BUILD_MANUALS}" = "y" ]; then
            CT_DoLog EXTRA "Building and installing the C library manual"
            # Omit JOBSFLAGS as GLIBC has problems building the
            # manuals in parallel
            CT_DoExecLog ALL make pdf html
            # EGLIBC doesn't have a install-{pdf.html}, and older
            # versions leave the manuals in the source directory
            CT_DoExecLog ALL mkdir -p ${CT_PREFIX_DIR}/share/doc
            if [ "${CT_LIBC_EGLIBC_2_16_or_later}" = "y" ]; then
                CT_DoExecLog ALL cp -av manual/*.pdf manual/libc \
                    ${CT_PREFIX_DIR}/share/doc
            else
                CT_DoExecLog ALL cp -av ${src_dir}/manual/*.pdf ${src_dir}/manual/libc \
                    ${CT_PREFIX_DIR}/share/doc
            fi
        fi

        if [ "${CT_LIBC_LOCALES}" = "y" ]; then
            do_libc_locales
        fi
    fi # libc_full == y
}

# Build up the addons list, separated with $1
do_libc_add_ons_list() {
    local sep="$1"
    local addons_list="$( echo "${CT_LIBC_ADDONS_LIST}"         \
                          |sed -r -e "s/[[:space:],]/${sep}/g;" \
                        )"
    case "${CT_THREADS}" in
        none)   ;;
        *)      addons_list="${addons_list}${sep}${CT_THREADS}";;
    esac
    [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && addons_list="${addons_list}${sep}ports"
    # Remove duplicate, leading and trailing separators
    echo "${addons_list}" |sed -r -e "s/${sep}+/${sep}/g; s/^${sep}//; s/${sep}\$//;"
}

# Compute up the minimum supported Linux kernel version
do_libc_min_kernel_config() {
    local min_kernel_config

    case "${CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY[*]}" in
        *--enable-kernel*) ;;
        *)  if [ "${CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS}" = "y" ]; then
                # We can't rely on the kernel version from the configuration,
                # because it might not be available if the user uses pre-installed
                # headers. On the other hand, both method will have the kernel
                # version installed in "usr/include/linux/version.h" in the sysroot.
                # Parse that instead of having two code-paths.
                version_code_file="${CT_SYSROOT_DIR}/usr/include/linux/version.h"
                if [ ! -f "${version_code_file}" -o ! -r "${version_code_file}" ]; then
                    CT_Abort "Linux version is unavailable in installed headers files"
                fi
                version_code="$( grep -E LINUX_VERSION_CODE "${version_code_file}"  \
                                 |cut -d ' ' -f 3                                   \
                               )"
                version=$(((version_code>>16)&0xFF))
                patchlevel=$(((version_code>>8)&0xFF))
                sublevel=$((version_code&0xFF))
                min_kernel_config="${version}.${patchlevel}.${sublevel}"
            elif [ "${CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN}" = "y" ]; then
                # Trim the fourth part of the linux version, keeping only the first three numbers
                min_kernel_config="$( echo "${CT_LIBC_GLIBC_MIN_KERNEL_VERSION}"            \
                                      |sed -r -e 's/^([^.]+\.[^.]+\.[^.]+)(|\.[^.]+)$/\1/;' \
                                    )"
            fi
            echo "--enable-kernel=${min_kernel_config}"
            ;;
    esac
}
