scripts/build/libc/glibc-eglibc.sh-common
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Mon Feb 21 23:39:46 2011 +0100 (2011-02-21)
changeset 2312 8b9938edd3d8
parent 2289 165eff2a1e10
child 2313 6336f985e2c0
permissions -rw-r--r--
libc/glibc: add fortify option

By default, recent versions of glibc and eglibc will build some
functions that take format strings (eg. printf, syslog...) with
run-time checks against some format string attacks. This is
called a fortified build.

Unfortunately, this fails somehow while building the instrumented
version of syslog, with some kind of circular dependency...

Disable fortified builds by default, and hide the enabling option
behind EXPERIMENTAL for daring users...

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
yann@2270
     1
# This file contains the functions common to glibc and eglibc
yann@850
     2
yann@2270
     3
# Build and install headers and start files
yann@850
     4
do_libc_start_files() {
yann@2271
     5
    local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
yann@2271
     6
yann@2277
     7
    CT_DoStep INFO "Installing C library headers & start files"
yann@850
     8
yann@850
     9
    mkdir -p "${CT_BUILD_DIR}/build-libc-startfiles"
yann@850
    10
    cd "${CT_BUILD_DIR}/build-libc-startfiles"
yann@850
    11
yann@850
    12
    CT_DoLog EXTRA "Configuring C library"
yann@850
    13
yann@2271
    14
    case "${CT_LIBC}" in
yann@2271
    15
        eglibc)
yann@2271
    16
            if [ "${CT_EGLIBC_CUSTOM_CONFIG}" = "y" ]; then
yann@2271
    17
                CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/eglibc.config" option-groups.config
yann@2271
    18
            fi
yann@2271
    19
            ;;
yann@2271
    20
    esac
avrac@1569
    21
yann@850
    22
    cross_cc=$(CT_Which "${CT_TARGET}-gcc")
yann@850
    23
    cross_cxx=$(CT_Which "${CT_TARGET}-g++")
yann@850
    24
    cross_ar=$(CT_Which "${CT_TARGET}-ar")
yann@850
    25
    cross_ranlib=$(CT_Which "${CT_TARGET}-ranlib")
yann@2271
    26
yann@850
    27
    CT_DoLog DEBUG "Using gcc for target: '${cross_cc}'"
yann@850
    28
    CT_DoLog DEBUG "Using g++ for target: '${cross_cxx}'"
yann@850
    29
    CT_DoLog DEBUG "Using ar for target: '${cross_ar}'"
yann@850
    30
    CT_DoLog DEBUG "Using ranlib for target: '${cross_ranlib}'"
yann@850
    31
yann@2289
    32
    touch config.cache
yann@2289
    33
    if [ "${CT_LIBC_GLIBC_FORCE_UNWIND}" = "y" ]; then
yann@2289
    34
        echo "libc_cv_forced_unwind=yes" >>config.cache
yann@2289
    35
        echo "libc_cv_c_cleanup=yes" >>config.cache
yann@2289
    36
    fi
yann@2289
    37
yann@2289
    38
    # Pre-seed the configparms file with values from the config option
yann@2289
    39
    printf "${CT_LIBC_GLIBC_CONFIGPARMS}\n" > configparms
yann@2289
    40
yann@1123
    41
    BUILD_CC="${CT_BUILD}-gcc"                          \
yann@1123
    42
    CC=${cross_cc}                                      \
yann@1123
    43
    CXX=${cross_cxx}                                    \
yann@1123
    44
    AR=${cross_ar}                                      \
yann@1123
    45
    RANLIB=${cross_ranlib}                              \
anthony@2154
    46
    CT_DoExecLog CFG                                    \
yann@2271
    47
    "${src_dir}/configure"                              \
yann@1123
    48
        --prefix=/usr                                   \
yann@1123
    49
        --with-headers="${CT_HEADERS_DIR}"              \
yann@1123
    50
        --build="${CT_BUILD}"                           \
yann@1123
    51
        --host="${CT_TARGET}"                           \
yann@2289
    52
        --cache-file="$(pwd)/config.cache"              \
yann@1123
    53
        --disable-profile                               \
yann@1123
    54
        --without-gd                                    \
yann@1123
    55
        --without-cvs                                   \
yann@850
    56
        --enable-add-ons
yann@850
    57
yann@850
    58
    CT_DoLog EXTRA "Installing C library headers"
yann@850
    59
yann@850
    60
    # use the 'install-headers' makefile target to install the
yann@850
    61
    # headers
yann@2277
    62
    CT_DoExecLog ALL make ${JOBSFLAGS}              \
yann@2277
    63
                     install_root=${CT_SYSROOT_DIR} \
yann@2277
    64
                     install-bootstrap-headers=yes  \
yann@2277
    65
                     install-headers
yann@850
    66
yann@2272
    67
    # For glibc, a few headers need to be manually installed
yann@2272
    68
    if [ "${CT_LIBC}" = "glibc" ]; then
yann@2272
    69
        # Two headers -- stubs.h and features.h -- aren't installed by install-headers,
yann@2272
    70
        # so do them by hand.  We can tolerate an empty stubs.h for the moment.
yann@2272
    71
        # See e.g. http://gcc.gnu.org/ml/gcc/2002-01/msg00900.html
yann@2272
    72
        mkdir -p "${CT_HEADERS_DIR}/gnu"
yann@2272
    73
        CT_DoExecLog ALL touch "${CT_HEADERS_DIR}/gnu/stubs.h"
yann@2272
    74
        CT_DoExecLog ALL cp -v "${CT_SRC_DIR}/glibc-${CT_LIBC_VERSION}/include/features.h"  \
yann@2272
    75
                               "${CT_HEADERS_DIR}/features.h"
yann@2272
    76
yann@2272
    77
        # Building the bootstrap gcc requires either setting inhibit_libc, or
yann@2272
    78
        # having a copy of stdio_lim.h... see
yann@2272
    79
        # http://sources.redhat.com/ml/libc-alpha/2003-11/msg00045.html
yann@2272
    80
        CT_DoExecLog ALL cp -v bits/stdio_lim.h "${CT_HEADERS_DIR}/bits/stdio_lim.h"
yann@2272
    81
yann@2272
    82
        # Following error building gcc-4.0.0's gcj:
yann@2272
    83
        #  error: bits/syscall.h: No such file or directory
yann@2272
    84
        # solved by following copy; see http://sourceware.org/ml/crossgcc/2005-05/msg00168.html
yann@2272
    85
        # but it breaks arm, see http://sourceware.org/ml/crossgcc/2006-01/msg00091.html
yann@2272
    86
        [ "${CT_ARCH}" != "arm" ] && CT_DoExecLog ALL cp -v misc/syscall-list.h "${CT_HEADERS_DIR}/bits/syscall.h" || true
yann@2272
    87
    fi
yann@2272
    88
yann@850
    89
    CT_DoLog EXTRA "Installing C library start files"
yann@850
    90
yann@850
    91
    # there are a few object files needed to link shared libraries,
yann@850
    92
    # which we build and install by hand
yann@2271
    93
    CT_DoExecLog ALL mkdir -p "${CT_SYSROOT_DIR}/usr/lib"
yann@2277
    94
    CT_DoExecLog ALL make ${JOBSFLAGS} csu/subdir_lib
yann@850
    95
    CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o \
yann@2271
    96
                        "${CT_SYSROOT_DIR}/usr/lib"
yann@850
    97
yann@2271
    98
    # Finally, 'libgcc_s.so' requires a 'libc.so' to link against.
yann@2271
    99
    # However, since we will never actually execute its code,
yann@2271
   100
    # it doesn't matter what it contains.  So, treating '/dev/null'
yann@850
   101
    # as a C source file, we produce a dummy 'libc.so' in one step
yann@2271
   102
    CT_DoExecLog ALL "${cross_cc}" -nostdlib        \
yann@2271
   103
                                   -nostartfiles    \
yann@2271
   104
                                   -shared          \
yann@2271
   105
                                   -x c /dev/null   \
yann@2271
   106
                                   -o "${CT_SYSROOT_DIR}/usr/lib/libc.so"
yann@850
   107
yann@850
   108
    CT_EndStep
yann@850
   109
}
yann@850
   110
yann@2270
   111
# This function builds and install the full C library
yann@850
   112
do_libc() {
yann@2271
   113
    local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
yann@2276
   114
    local extra_cc_args
yann@1478
   115
    local -a extra_config
yann@2271
   116
    local -a extra_make_args
yann@2312
   117
    local glibc_cflags
yann@1478
   118
yann@850
   119
    CT_DoStep INFO "Installing C library"
yann@850
   120
yann@850
   121
    mkdir -p "${CT_BUILD_DIR}/build-libc"
yann@850
   122
    cd "${CT_BUILD_DIR}/build-libc"
yann@850
   123
yann@850
   124
    CT_DoLog EXTRA "Configuring C library"
yann@850
   125
yann@2271
   126
    case "${CT_LIBC}" in
yann@2271
   127
        eglibc)
yann@2271
   128
            if [ "${CT_EGLIBC_CUSTOM_CONFIG}" = "y" ]; then
yann@2271
   129
                CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/eglibc.config" option-groups.config
yann@2271
   130
            fi
yann@2271
   131
            if [ "${CT_EGLIBC_OPT_SIZE}" = "y" ]; then
yann@2271
   132
                OPTIMIZE=-Os
yann@2271
   133
            else
yann@2271
   134
                OPTIMIZE=-O2
yann@2271
   135
            fi
yann@2271
   136
            ;;
yann@2276
   137
        glibc)
yann@2276
   138
            # glibc can't be built without -O2 (reference needed!)
yann@2276
   139
            OPTIMIZE=-O2
yann@2276
   140
            # Also, if those two are missing, iconv build breaks
yann@2276
   141
            extra_config+=( --disable-debug --disable-sanity-checks )
yann@2276
   142
            ;;
yann@2271
   143
    esac
richard@1796
   144
yann@850
   145
    # Add some default glibc config options if not given by user.
yann@850
   146
    # We don't need to be conditional on wether the user did set different
yann@850
   147
    # values, as they CT_LIBC_GLIBC_EXTRA_CONFIG is passed after extra_config
yann@850
   148
yann@2273
   149
    extra_config+=("$(do_libc_min_kernel_config)")
yann@850
   150
yann@850
   151
    case "${CT_THREADS}" in
yann@1478
   152
        nptl)           extra_config+=("--with-__thread" "--with-tls");;
yann@1478
   153
        linuxthreads)   extra_config+=("--with-__thread" "--without-tls" "--without-nptl");;
yann@1478
   154
        none)           extra_config+=("--without-__thread" "--without-nptl")
yann@850
   155
                        case "${CT_LIBC_GLIBC_EXTRA_CONFIG}" in
yann@850
   156
                            *-tls*) ;;
yann@1478
   157
                            *) extra_config+=("--without-tls");;
yann@850
   158
                        esac
yann@850
   159
                        ;;
yann@850
   160
    esac
yann@850
   161
yann@850
   162
    case "${CT_SHARED_LIBS}" in
yann@1478
   163
        y) extra_config+=("--enable-shared");;
yann@1478
   164
        *) extra_config+=("--disable-shared");;
yann@850
   165
    esac
yann@850
   166
yann@850
   167
    case "${CT_ARCH_FLOAT_HW},${CT_ARCH_FLOAT_SW}" in
yann@1478
   168
        y,) extra_config+=("--with-fp");;
yann@1478
   169
        ,y) extra_config+=("--without-fp");;
yann@850
   170
    esac
yann@850
   171
bryanhundven@2180
   172
    if [ "${CT_LIBC_DISABLE_VERSIONING}" = "y" ]; then
bryanhundven@2180
   173
        extra_config+=("--disable-versioning")
bryanhundven@2180
   174
    fi
bryanhundven@2180
   175
bryanhundven@2181
   176
    if [ "${CT_LIBC_OLDEST_ABI}" != "" ]; then
bryanhundven@2181
   177
        extra_config+=("--enable-oldest-abi=${CT_LIBC_OLDEST_ABI}")
bryanhundven@2181
   178
    fi
bryanhundven@2181
   179
yann@850
   180
    case "$(do_libc_add_ons_list ,)" in
yann@850
   181
        "") ;;
yann@1478
   182
        *)  extra_config+=("--enable-add-ons=$(do_libc_add_ons_list ,)");;
yann@850
   183
    esac
yann@850
   184
yann@850
   185
    extra_cc_args="${extra_cc_args} ${CT_ARCH_ENDIAN_OPT}"
yann@850
   186
yann@2289
   187
    touch config.cache
yann@2289
   188
    if [ "${CT_LIBC_GLIBC_FORCE_UNWIND}" = "y" ]; then
yann@2289
   189
        echo "libc_cv_forced_unwind=yes" >>config.cache
yann@2289
   190
        echo "libc_cv_c_cleanup=yes" >>config.cache
yann@2289
   191
    fi
yann@2289
   192
yann@2276
   193
    # Pre-seed the configparms file with values from the config option
yann@2276
   194
    printf "${CT_LIBC_GLIBC_CONFIGPARMS}\n" > configparms
yann@2276
   195
yann@850
   196
    cross_cc=$(CT_Which "${CT_TARGET}-gcc")    
yann@850
   197
yann@850
   198
    CT_DoLog DEBUG "Using gcc for target:     '${cross_cc}'"
yann@850
   199
    CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'"
yann@1478
   200
    CT_DoLog DEBUG "Extra config args passed: '${extra_config[*]}'"
yann@850
   201
    CT_DoLog DEBUG "Extra CC args passed    : '${extra_cc_args}'"
yann@850
   202
yann@2312
   203
    glibc_cflags="${CT_TARGET_CFLAGS} ${CT_LIBC_GLIBC_EXTRA_CFLAGS} ${OPTIMIZE}"
yann@2312
   204
    case "${CT_LIBC_ENABLE_FORTIFIED_BUILD}" in
yann@2312
   205
        y)  ;;
yann@2312
   206
        *)  glibc_cflags+=" -U_FORTIFY_SOURCE";;
yann@2312
   207
    esac
yann@2312
   208
bryanhundven@2229
   209
    # ./configure is mislead by our tools override wrapper for bash
bryanhundven@2229
   210
    # so just tell it where the real bash is _on_the_target_!
bryanhundven@2229
   211
    # Notes:
bryanhundven@2229
   212
    # - ${ac_cv_path_BASH_SHELL} is only used to set BASH_SHELL
bryanhundven@2229
   213
    # - ${BASH_SHELL}            is only used to set BASH
bryanhundven@2229
   214
    # - ${BASH}                  is only used to set the shebang
bryanhundven@2229
   215
    #                            in two scripts to run on the target
bryanhundven@2229
   216
    # So we can safely bypass bash detection at compile time.
bryanhundven@2229
   217
    # Should this change in a future eglibc release, we'd better
bryanhundven@2229
   218
    # directly mangle the generated scripts _after_ they get built,
bryanhundven@2229
   219
    # or even after they get installed... eglibc is such a sucker...
yann@2289
   220
    echo "ac_cv_path_BASH_SHELL=/bin/bash" >>config.cache
bryanhundven@2229
   221
yann@2276
   222
    # Configure with --prefix the way we want it on the target...
yann@2276
   223
    # There are a whole lot of settings here.  You'll probably want
yann@2276
   224
    # to read up on what they all mean, and customize a bit, possibly by setting GLIBC_EXTRA_CONFIG
yann@2276
   225
    # Compare these options with the ones used when installing the glibc headers above - they're different.
yann@2276
   226
    # Adding "--without-gd" option to avoid error "memusagestat.c:36:16: gd.h: No such file or directory"
yann@2276
   227
    # See also http://sources.redhat.com/ml/libc-alpha/2000-07/msg00024.html.
yann@2276
   228
    # Set BUILD_CC, or we won't be able to build datafiles
yann@2276
   229
yann@1041
   230
    BUILD_CC="${CT_BUILD}-gcc"                                      \
yann@2312
   231
    CFLAGS="${glibc_cflags}"                                        \
yann@850
   232
    CC="${CT_TARGET}-gcc ${CT_LIBC_EXTRA_CC_ARGS} ${extra_cc_args}" \
yann@850
   233
    AR=${CT_TARGET}-ar                                              \
yann@850
   234
    RANLIB=${CT_TARGET}-ranlib                                      \
anthony@2154
   235
    CT_DoExecLog CFG                                                \
yann@2271
   236
    "${src_dir}/configure"                                          \
yann@850
   237
        --prefix=/usr                                               \
yann@1041
   238
        --build=${CT_BUILD}                                         \
yann@850
   239
        --host=${CT_TARGET}                                         \
yann@2289
   240
        --cache-file="$(pwd)/config.cache"                          \
yann@2276
   241
        --without-cvs                                               \
yann@850
   242
        --disable-profile                                           \
yann@850
   243
        --without-gd                                                \
yann@2276
   244
        --with-headers="${CT_HEADERS_DIR}"                          \
yann@1478
   245
        "${extra_config[@]}"                                        \
yann@850
   246
        ${CT_LIBC_GLIBC_EXTRA_CONFIG}
yann@850
   247
    
yann@2276
   248
    # build hacks
yann@2276
   249
    case "${CT_ARCH},${CT_ARCH_CPU}" in
yann@2276
   250
        powerpc,8??)
yann@2276
   251
            # http://sourceware.org/ml/crossgcc/2008-10/msg00068.html
yann@2276
   252
            CT_DoLog DEBUG "Activating support for memset on broken ppc-8xx (CPU15 erratum)"
yann@2276
   253
            extra_make_args+=( ASFLAGS="-DBROKEN_PPC_8xx_CPU15" )
yann@2271
   254
            ;;
yann@1328
   255
    esac
yann@1328
   256
yann@2276
   257
    CT_DoLog EXTRA "Building C library"
yann@2277
   258
    CT_DoExecLog ALL make ${JOBSFLAGS}                      \
yann@2276
   259
                          "${extra_make_args[@]}"           \
yann@2276
   260
                          all
yann@850
   261
yann@850
   262
    CT_DoLog EXTRA "Installing C library"
yann@2277
   263
    CT_DoExecLog ALL make ${JOBSFLAGS}                      \
yann@2276
   264
                          "${extra_make_args[@]}"           \
yann@2276
   265
                          install_root="${CT_SYSROOT_DIR}"  \
yann@2276
   266
                          install
yann@850
   267
yann@850
   268
    CT_EndStep
yann@850
   269
}
yann@850
   270
yann@2270
   271
# This function finishes the C library install
yann@2270
   272
# This is a no-op
yann@850
   273
do_libc_finish() {
yann@850
   274
    :
yann@850
   275
}
yann@850
   276
yann@850
   277
# Build up the addons list, separated with $1
yann@850
   278
do_libc_add_ons_list() {
yann@850
   279
    local sep="$1"
yann@2274
   280
    local addons_list="$( echo "${CT_LIBC_ADDONS_LIST}"         \
yann@2274
   281
                          |sed -r -e "s/[[:space:],]/${sep}/g;" \
yann@2274
   282
                        )"
yann@850
   283
    case "${CT_THREADS}" in
yann@850
   284
        none)   ;;
yann@850
   285
        *)      addons_list="${addons_list}${sep}${CT_THREADS}";;
yann@850
   286
    esac
yann@850
   287
    [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && addons_list="${addons_list}${sep}ports"
yann@2274
   288
    # Remove duplicate, leading and trailing separators
yann@2274
   289
    echo "${addons_list}" |sed -r -e "s/${sep}+/${sep}/g; s/^${sep}//; s/${sep}\$//;"
yann@850
   290
}
yann@2273
   291
yann@2273
   292
# Compute up the minimum supported Linux kernel version
yann@2273
   293
do_libc_min_kernel_config() {
yann@2273
   294
    local min_kernel_config
yann@2273
   295
yann@2273
   296
    case "${CT_LIBC_GLIBC_EXTRA_CONFIG}" in
yann@2273
   297
        *--enable-kernel*) ;;
yann@2273
   298
        *)  if [ "${CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS}" = "y" ]; then
yann@2273
   299
                # We can't rely on the kernel version from the configuration,
yann@2273
   300
                # because it might not be available if the user uses pre-installed
yann@2273
   301
                # headers. On the other hand, both method will have the kernel
yann@2279
   302
                # version installed in "usr/include/linux/version.h" in the sysroot.
yann@2273
   303
                # Parse that instead of having two code-paths.
yann@2273
   304
                version_code_file="${CT_SYSROOT_DIR}/usr/include/linux/version.h"
yann@2273
   305
                if [ ! -f "${version_code_file}" -o ! -r "${version_code_file}" ]; then
yann@2273
   306
                    CT_Abort "Linux version is unavailable in installed headers files"
yann@2273
   307
                fi
yann@2273
   308
                version_code="$( grep -E LINUX_VERSION_CODE "${version_code_file}"  \
yann@2273
   309
                                 |cut -d ' ' -f 3                                   \
yann@2273
   310
                               )"
yann@2273
   311
                version=$(((version_code>>16)&0xFF))
yann@2273
   312
                patchlevel=$(((version_code>>8)&0xFF))
yann@2273
   313
                sublevel=$((version_code&0xFF))
yann@2273
   314
                min_kernel_config="${version}.${patchlevel}.${sublevel}"
yann@2273
   315
            elif [ "${CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN}" = "y" ]; then
yann@2273
   316
                # Trim the fourth part of the linux version, keeping only the first three numbers
yann@2276
   317
                min_kernel_config="$( echo "${CT_LIBC_GLIBC_MIN_KERNEL_VERSION}"            \
yann@2276
   318
                                      |sed -r -e 's/^([^.]+\.[^.]+\.[^.]+)(|\.[^.]+)$/\1/;' \
yann@2273
   319
                                    )"
yann@2273
   320
            fi
yann@2273
   321
            echo "--enable-kernel=${min_kernel_config}"
yann@2273
   322
            ;;
yann@2273
   323
    esac
yann@2273
   324
}