[PATCH] glibc: Refactor startfiles/headers into do_libc_backend()

Bryan Hundven bryanhundven@gmail.com
Thu Jun 23 09:20:00 GMT 2011


On Wed, Jun 22, 2011 at 11:19 PM, Bryan Hundven <bryanhundven@gmail.com> wrote:
> # HG changeset patch
> # User Bryan Hundven <bryanhundven@gmail.com>
> # Date 1308809915 25200
> # Node ID 54b9dc8f9f00dce0653534c54fe2c1f6667ecc37
> # Parent  8bb5151c5b01fb4d1ab7bc48cec563a1e6277304
> glibc: Refactor startfiles/headers into do_libc_backend()
>
> Refactor the contents of 'do_libc_start_files()' and 'do_libc()' into a
> parameterized 'do_libc_backend()'. 'do_libc_start_files()' and 'do_libc()'
> call 'do_libc_backend()' with either 'startfile_mode=yes' or
> 'startfile_mode=no' (respectively) so that the startfiles/headers and
> the libc builds are configured and built with the same options.
>
> One example of where this is needed is when building a mips toolchain.
> Previously, if you were building an n32 toolchain, you wouldn't have
> noticed an issue, because if '-mabi' is not in CFLAGS, n32 is the
> default:
>
> http://sourceware.org/git/?p=glibc-ports.git;a=blob;f=sysdeps/mips/preconfigure;hb=HEAD
>
> But when trying to build an o32 or n64 toolchain the build would
> have failed. This is because (e)glibc expects "-mabi={o32,n32,n64}" to be
> in CFLAGS, but was not previously provided in 'do_libc_start_files()'.
> The build failure would happen in the shared-core gcc when it tries to
> configure an n64 or o32 gcc with an n32 libc.
>
> A simpler solution would have been to just add TARGET_CFLAGS to configure
> in 'do_libc_start_files()', but this way makes configure and make
> consistent for both steps.
>
> Signed-off-by: Bryan Hundven <bryanhundven@gmail.com>
>
> diff -r 8bb5151c5b01 -r 54b9dc8f9f00 scripts/build/libc/glibc-eglibc.sh-common
> --- a/scripts/build/libc/glibc-eglibc.sh-common Wed Jun 22 22:54:14 2011 +0200
> +++ b/scripts/build/libc/glibc-eglibc.sh-common Wed Jun 22 23:18:35 2011 -0700
> @@ -51,128 +51,34 @@
>
>  # Build and install headers and start files
>  do_libc_start_files() {
> -    local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
> -
> -    CT_DoStep INFO "Installing C library headers & start files"
> -
> -    mkdir -p "${CT_BUILD_DIR}/build-libc-startfiles"
> -    cd "${CT_BUILD_DIR}/build-libc-startfiles"
> -
> -    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
> -            ;;
> -    esac
> -
> -    cross_cc=$(CT_Which "${CT_TARGET}-gcc")
> -    cross_cxx=$(CT_Which "${CT_TARGET}-g++")
> -    cross_ar=$(CT_Which "${CT_TARGET}-ar")
> -    cross_ranlib=$(CT_Which "${CT_TARGET}-ranlib")
> -
> -    CT_DoLog DEBUG "Using gcc for target: '${cross_cc}'"
> -    CT_DoLog DEBUG "Using g++ for target: '${cross_cxx}'"
> -    CT_DoLog DEBUG "Using ar for target: '${cross_ar}'"
> -    CT_DoLog DEBUG "Using ranlib for target: '${cross_ranlib}'"
> -
> -    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 "${CT_LIBC_GLIBC_CONFIGPARMS}\n" > configparms
> -
> -    CT_DoExecLog CFG                                    \
> -    BUILD_CC="${CT_BUILD}-gcc"                          \
> -    CC=${cross_cc}                                      \
> -    CXX=${cross_cxx}                                    \
> -    AR=${cross_ar}                                      \
> -    RANLIB=${cross_ranlib}                              \
> -    "${src_dir}/configure"                              \
> -        --prefix=/usr                                   \
> -        --with-headers="${CT_HEADERS_DIR}"              \
> -        --build="${CT_BUILD}"                           \
> -        --host="${CT_TARGET}"                           \
> -        --cache-file="$(pwd)/config.cache"              \
> -        --disable-profile                               \
> -        --without-gd                                    \
> -        --without-cvs                                   \
> -        --enable-add-ons
> -
> -    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} \
> -                     install-bootstrap-headers=yes  \
> -                     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
> -        case "${CT_ARCH}" in
> -            arm)    ;;
> -            *)  CT_DoExecLog ALL cp -v "misc/syscall-list.h"            \
> -                                       "${CT_HEADERS_DIR}/bits/syscall.h"
> -                ;;
> -        esac
> -    fi
> -
> -    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}/usr/lib"
> -        CT_DoExecLog ALL make ${JOBSFLAGS} csu/subdir_lib
> -        CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o \
> -                            "${CT_SYSROOT_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}/usr/lib/libc.so"
> -    fi # threads == nptl
> -
> -    CT_EndStep
> +    # Start files and Headers should be configured the same way as the
> +    # final libc, but built and installed differently.
> +    do_libc_backend startfile_mode=yes
>  }
>
>  # This function builds and install the full C library
>  do_libc() {
> +    do_libc_backend startfile_mode=no
> +}
> +
> +do_libc_backend() {
>     local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
> +    startfile_mode=no
>     local extra_cc_args
>     local -a extra_config
>     local -a extra_make_args
>     local glibc_cflags
>
> -    CT_DoStep INFO "Installing C library"
> +    while [ $# -ne 0 ]; do
> +        eval "${1}"
> +        shift
> +    done
> +
> +    if [ "${startfile_mode}" = "yes" ]; then
> +        CT_DoStep INFO "Installing C library headers & start files"
> +    else
> +        CT_DoStep INFO "Installing C library"
> +    fi
>
>     mkdir -p "${CT_BUILD_DIR}/build-libc"
>     cd "${CT_BUILD_DIR}/build-libc"
> @@ -316,16 +222,78 @@
>             ;;
>     esac
>
> -    CT_DoLog EXTRA "Building C library"
> -    CT_DoExecLog ALL make ${JOBSFLAGS}                      \
> -                          "${extra_make_args[@]}"           \
> -                          all
> +    if [ "${startfile_mode}" = "yes" ]; then
> +        CT_DoLog EXTRA "Installing C library headers"
>
> -    CT_DoLog EXTRA "Installing C library"
> -    CT_DoExecLog ALL make ${JOBSFLAGS}                      \
> -                          "${extra_make_args[@]}"           \
> -                          install_root="${CT_SYSROOT_DIR}"  \
> -                          install
> +        # use the 'install-headers' makefile target to install the
> +        # headers
> +        CT_DoExecLog ALL make ${JOBSFLAGS}              \
> +                         install_root=${CT_SYSROOT_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
> +            case "${CT_ARCH}" in
> +                arm)    ;;
> +                *)  CT_DoExecLog ALL cp -v "misc/syscall-list.h"            \
> +                                           "${CT_HEADERS_DIR}/bits/syscall.h"
> +                    ;;
> +            esac
> +        fi
> +
> +        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}/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}/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}/usr/lib/libc.so"
> +        fi # threads == nptl
> +    else # startfile_mode = no
> +        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}"  \
> +                              install
> +    fi
>
>     CT_EndStep
>  }
>

Yann,

I tested builds of:

mips64-octeon-linux-gnu (eglibc 2.14) (still testing sample... will
commit when it passes more test-suite tests on my cn3120, and a kernel
runs... at least it builds ;) )
powerpc-e500v2-linux-gnuspe (eglibc 2.14)
armeb-unknown-linux-gnueabi (glibc 2.13)
i686-nptl-linux-gnu (glibc 2.13)

..on an x86_64 host.

I noticed that both the armeb and i686 builds required unwind support.
Must be because I'm building on x86_64?

From CT_LIBC_GLIBC_FORCE_UNWIND help:
----------------------------------------------------------------------
The issue seems to be related to building NPTL on old versions
of glibc (and possibly eglibc as well) on some architectures
(seen on s390, s390x and x86_64).
----------------------------------------------------------------------

Does this mean when building on these platforms, or when building
cross tools targeted for these platforms?

I only noticed this issue with glibc, and not with eglibc.

-Bryan


More information about the crossgcc mailing list