yann@850: # eglibc build functions (initially by Thomas JOURDAN). yann@850: yann@850: # Download eglibc repository yann@850: do_eglibc_get() { yann@850: CT_HasOrAbort svn yann@850: yann@850: case "${CT_LIBC_VERSION}" in yann@850: trunk) svn_url="svn://svn.eglibc.org/trunk";; yann@850: *) svn_url="svn://svn.eglibc.org/branches/eglibc-${CT_LIBC_VERSION}";; yann@850: esac yann@850: yann@850: case "${CT_EGLIBC_CHECKOUT}" in yann@850: y) svn_action="checkout";; yann@850: *) svn_action="export --force";; yann@850: esac yann@850: yann@850: CT_DoExecLog ALL svn ${svn_action} -r "${CT_EGLIBC_REVISION:-HEAD}" "${svn_url}" . 2>&1 yann@850: yann@850: # Compress eglibc yann@1123: CT_DoExecLog ALL mv libc "eglibc-${CT_LIBC_VERSION}" yann@1123: CT_DoExecLog ALL tar cjf "eglibc-${CT_LIBC_VERSION}.tar.bz2" "eglibc-${CT_LIBC_VERSION}" yann@850: yann@850: # Compress linuxthreads, localedef and ports yann@850: # Assign them the name the way ct-ng like it yann@850: for addon in linuxthreads localedef ports; do yann@1123: CT_DoExecLog ALL mv "${addon}" "eglibc-${addon}-${CT_LIBC_VERSION}" yann@1123: CT_DoExecLog ALL tar cjf "eglibc-${addon}-${CT_LIBC_VERSION}.tar.bz2" "eglibc-${addon}-${CT_LIBC_VERSION}" yann@850: done yann@850: } yann@850: yann@850: # Download glibc yann@850: do_libc_get() { yann@850: # eglibc is only available through subversion, there are no yann@850: # snapshots available. Moreover, addons will be downloaded yann@850: # simultaneously. yann@850: yann@850: # build filename yann@1123: eglibc="eglibc-${CT_LIBC_VERSION}.tar.bz2" yann@850: eglibc_linuxthreads="${CT_LIBC}-linuxthreads-${CT_LIBC_VERSION}.tar.bz2" yann@850: eglibc_localedef="${CT_LIBC}-localedef-${CT_LIBC_VERSION}.tar.bz2" yann@850: eglibc_ports="${CT_LIBC}-ports-${CT_LIBC_VERSION}.tar.bz2" yann@850: yann@850: # Check if every tarballs are already present yann@1476: if [ -f "${CT_TARBALLS_DIR}/${eglibc}" \ yann@1476: -a -f "${CT_TARBALLS_DIR}/${eglibc_linuxthreads}" \ yann@1476: -a -f "${CT_TARBALLS_DIR}/${eglibc_localedef}" \ yann@1476: -a -f "${CT_TARBALLS_DIR}/${eglibc_ports}" \ yann@1476: ]; then yann@850: CT_DoLog DEBUG "Already have 'eglibc-${CT_LIBC_VERSION}'" yann@850: return 0 yann@850: fi yann@850: yann@1476: if [ -f "${CT_LOCAL_TARBALLS_DIR}/${eglibc}" \ yann@1476: -a -f "${CT_LOCAL_TARBALLS_DIR}/${eglibc_linuxthreads}" \ yann@1476: -a -f "${CT_LOCAL_TARBALLS_DIR}/${eglibc_localedef}" \ yann@1476: -a -f "${CT_LOCAL_TARBALLS_DIR}/${eglibc_ports}" \ yann@1528: -a "${CT_FORCE_DOWNLOAD}" != "y" \ yann@1476: ]; then yann@850: CT_DoLog DEBUG "Got 'eglibc-${CT_LIBC_VERSION}' from local storage" yann@850: for file in ${eglibc} ${eglibc_linuxthreads} ${eglibc_localedef} ${eglibc_ports}; do yann@850: CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${file}" "${CT_TARBALLS_DIR}/${file}" yann@850: done yann@850: return 0 yann@850: fi yann@850: yann@850: # Not found locally, try from the network yann@850: CT_DoLog EXTRA "Retrieving 'eglibc-${CT_LIBC_VERSION}'" yann@867: yann@867: CT_MktempDir tmp_dir yann@867: CT_Pushd "${tmp_dir}" yann@867: yann@850: do_eglibc_get yann@867: CT_DoLog DEBUG "Moving 'eglibc-${CT_LIBC_VERSION}' to tarball directory" yann@867: for file in ${eglibc} ${eglibc_linuxthreads} ${eglibc_localedef} ${eglibc_ports}; do yann@867: CT_DoExecLog ALL mv -f "${file}" "${CT_TARBALLS_DIR}" yann@867: done yann@867: yann@867: CT_Popd yann@867: yann@867: # Remove source files yann@867: CT_DoExecLog ALL rm -rf "${tmp_dir}" yann@850: yann@850: if [ "${CT_SAVE_TARBALLS}" = "y" ]; then yann@850: CT_DoLog EXTRA "Saving 'eglibc-${CT_LIBC_VERSION}' to local storage" yann@850: for file in ${eglibc} ${eglibc_linuxthreads} ${eglibc_localedef} ${eglibc_ports}; do yann@850: CT_DoExecLog ALL mv -f "${CT_TARBALLS_DIR}/${file}" "${CT_LOCAL_TARBALLS_DIR}" yann@850: CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${file}" "${CT_TARBALLS_DIR}/${file}" yann@850: done yann@850: fi yann@850: yann@850: return 0 yann@850: } yann@850: yann@850: # Extract eglibc yann@850: do_libc_extract() { yann@1126: CT_Extract "eglibc-${CT_LIBC_VERSION}" yann@1126: CT_Patch "eglibc-${CT_LIBC_VERSION}" yann@850: yann@850: # C library addons yann@850: for addon in $(do_libc_add_ons_list " "); do yann@850: # NPTL addon is not to be extracted, in any case yann@850: [ "${addon}" = "nptl" ] && continue || true yann@1123: CT_Pushd "${CT_SRC_DIR}/eglibc-${CT_LIBC_VERSION}" yann@1126: CT_Extract "eglibc-${addon}-${CT_LIBC_VERSION}" nochdir yann@1126: # Some addons have the 'long' name, while others have the yann@1126: # 'short' name, but patches are non-uniformly built with yann@1126: # either the 'long' or 'short' name, whatever the addons name yann@1126: # so we have to make symlinks from the existing to the missing yann@1126: # Fortunately for us, [ -d foo ], when foo is a symlink to a yann@1126: # directory, returns true! yann@1126: [ -d "${addon}" ] || ln -s "eglibc-${addon}-${CT_LIBC_VERSION}" "${addon}" yann@1126: [ -d "eglibc-${addon}-${CT_LIBC_VERSION}" ] || ln -s "${addon}" "eglibc-${addon}-${CT_LIBC_VERSION}" yann@1126: CT_Patch "eglibc-${addon}-${CT_LIBC_VERSION}" nochdir yann@1123: CT_Popd yann@850: done yann@850: yann@884: # The configure files may be older than the configure.in files yann@884: # if using a snapshot (or even some tarballs). Fake them being yann@884: # up to date. yann@1123: find "${CT_SRC_DIR}/eglibc-${CT_LIBC_VERSION}" -type f -name configure -exec touch {} \; 2>&1 |CT_DoLog ALL yann@884: yann@850: return 0 yann@850: } yann@850: avrac@1569: # Copy user provided eglibc configuration file if provided yann@850: do_libc_check_config() { avrac@1569: if [ "${CT_EGLIBC_CUSTOM_CONFIG}" != "y" ]; then avrac@1569: return 0 avrac@1569: fi avrac@1569: avrac@1569: CT_DoStep INFO "Checking C library configuration" avrac@1569: avrac@1569: CT_TestOrAbort "You did not provide an eglibc config file!" \ avrac@1569: -n "${CT_EGLIBC_OPTION_GROUPS_FILE}" -a \ avrac@1569: -f "${CT_EGLIBC_OPTION_GROUPS_FILE}" avrac@1569: avrac@1569: CT_DoExecLog ALL cp "${CT_EGLIBC_OPTION_GROUPS_FILE}" "${CT_CONFIG_DIR}/eglibc.config" avrac@1569: avrac@1569: # NSS configuration avrac@1569: if grep -E '^OPTION_EGLIBC_NSSWITCH[[:space:]]*=[[:space:]]*n' "${CT_EGLIBC_OPTION_GROUPS_FILE}" >/dev/null 2>&1; then avrac@1569: CT_DoLog DEBUG "Using fixed-configuration nsswitch facility" avrac@1569: avrac@1569: if [ "${CT_EGLIBC_BUNDLED_NSS_CONFIG}" = "y" ]; then avrac@1569: nss_config="${CT_SRC_DIR}/eglibc-${CT_LIBC_VERSION}/nss/fixed-nsswitch.conf" avrac@1569: else avrac@1569: nss_config="${CT_EGLIBC_NSS_CONFIG_FILE}" avrac@1569: fi avrac@1569: CT_TestOrAbort "NSS config file not found!" -n "${nss_config}" -a -f "${nss_config}" avrac@1569: avrac@1569: CT_DoExecLog ALL cp "${nss_config}" "${CT_CONFIG_DIR}/nsswitch.config" avrac@1569: echo "OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG = ${CT_CONFIG_DIR}/nsswitch.config" \ avrac@1569: >> "${CT_CONFIG_DIR}/eglibc.config" avrac@1569: avrac@1569: if [ "${CT_EGLIBC_BUNDLED_NSS_FUNCTIONS}" = "y" ]; then avrac@1569: nss_functions="${CT_SRC_DIR}/eglibc-${CT_LIBC_VERSION}/nss/fixed-nsswitch.functions" avrac@1569: else avrac@1569: nss_functions="${CT_EGLIBC_NSS_FUNCTIONS_FILE}" avrac@1569: fi avrac@1569: CT_TestOrAbort "NSS functions file not found!" -n "${nss_functions}" -a -f "${nss_functions}" avrac@1569: avrac@1569: CT_DoExecLog ALL cp "${nss_functions}" "${CT_CONFIG_DIR}/nsswitch.functions" avrac@1569: echo "OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS = ${CT_CONFIG_DIR}/nsswitch.functions" \ avrac@1569: >> "${CT_CONFIG_DIR}/eglibc.config" avrac@1569: else avrac@1569: CT_DoLog DEBUG "Using full-blown nsswitch facility" avrac@1569: fi avrac@1569: avrac@1569: CT_EndStep yann@850: } yann@850: yann@884: # This function installs the eglibc headers needed to build the core compiler yann@850: do_libc_headers() { yann@850: # Instead of doing two time the same actions, headers will yann@850: # be installed with start files yann@850: : yann@850: } yann@850: yann@850: # Build and install start files yann@850: do_libc_start_files() { yann@850: CT_DoStep INFO "Installing C library headers / start files" yann@850: yann@850: mkdir -p "${CT_BUILD_DIR}/build-libc-startfiles" yann@850: cd "${CT_BUILD_DIR}/build-libc-startfiles" yann@850: yann@850: CT_DoLog EXTRA "Configuring C library" yann@850: avrac@1569: if [ "${CT_EGLIBC_CUSTOM_CONFIG}" = "y" ]; then avrac@1569: CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/eglibc.config" option-groups.config avrac@1569: fi avrac@1569: yann@850: cross_cc=$(CT_Which "${CT_TARGET}-gcc") yann@850: cross_cxx=$(CT_Which "${CT_TARGET}-g++") yann@850: cross_ar=$(CT_Which "${CT_TARGET}-ar") yann@850: cross_ranlib=$(CT_Which "${CT_TARGET}-ranlib") yann@850: yann@850: CT_DoLog DEBUG "Using gcc for target: '${cross_cc}'" yann@850: CT_DoLog DEBUG "Using g++ for target: '${cross_cxx}'" yann@850: CT_DoLog DEBUG "Using ar for target: '${cross_ar}'" yann@850: CT_DoLog DEBUG "Using ranlib for target: '${cross_ranlib}'" yann@850: yann@1123: BUILD_CC="${CT_BUILD}-gcc" \ yann@1123: CC=${cross_cc} \ yann@1123: CXX=${cross_cxx} \ yann@1123: AR=${cross_ar} \ yann@1123: RANLIB=${cross_ranlib} \ yann@1123: CT_DoExecLog ALL \ yann@1123: "${CT_SRC_DIR}/eglibc-${CT_LIBC_VERSION}/configure" \ yann@1123: --prefix=/usr \ yann@1123: --with-headers="${CT_HEADERS_DIR}" \ yann@1123: --build="${CT_BUILD}" \ yann@1123: --host="${CT_TARGET}" \ yann@1123: --disable-profile \ yann@1123: --without-gd \ yann@1123: --without-cvs \ yann@850: --enable-add-ons yann@850: yann@850: CT_DoLog EXTRA "Installing C library headers" yann@850: yann@850: # use the 'install-headers' makefile target to install the yann@850: # headers yann@850: yann@850: CT_DoExecLog ALL \ yann@850: make install-headers \ yann@850: install_root=${CT_SYSROOT_DIR} \ yann@850: install-bootstrap-headers=yes yann@850: yann@850: CT_DoLog EXTRA "Installing C library start files" yann@850: yann@850: # there are a few object files needed to link shared libraries, yann@850: # which we build and install by hand yann@850: yann@850: CT_DoExecLog ALL mkdir -p ${CT_SYSROOT_DIR}/usr/lib yann@850: CT_DoExecLog ALL make csu/subdir_lib yann@850: CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o \ yann@850: ${CT_SYSROOT_DIR}/usr/lib yann@850: yann@850: # Finally, 'libgcc_s.so' requires a 'libc.so' to link against. yann@850: # However, since we will never actually execute its code, yann@850: # it doesn't matter what it contains. So, treating '/dev/null' yann@850: # as a C source file, we produce a dummy 'libc.so' in one step yann@850: yann@850: CT_DoExecLog ALL ${cross_cc} -nostdlib -nostartfiles -shared -x c /dev/null -o ${CT_SYSROOT_DIR}/usr/lib/libc.so yann@850: yann@850: CT_EndStep yann@850: } yann@850: yann@850: # This function builds and install the full glibc yann@850: do_libc() { yann@1478: local -a extra_config yann@1478: yann@850: CT_DoStep INFO "Installing C library" yann@850: yann@850: mkdir -p "${CT_BUILD_DIR}/build-libc" yann@850: cd "${CT_BUILD_DIR}/build-libc" yann@850: yann@850: CT_DoLog EXTRA "Configuring C library" yann@850: avrac@1569: if [ "${CT_EGLIBC_CUSTOM_CONFIG}" = "y" ]; then avrac@1569: CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/eglibc.config" option-groups.config avrac@1569: fi avrac@1569: yann@850: # Add some default glibc config options if not given by user. yann@850: # We don't need to be conditional on wether the user did set different yann@850: # values, as they CT_LIBC_GLIBC_EXTRA_CONFIG is passed after extra_config yann@850: yann@1478: extra_config+=("--enable-kernel=$(echo ${CT_LIBC_GLIBC_MIN_KERNEL} |sed -r -e 's/^([^.]+\.[^.]+\.[^.]+)(|\.[^.]+)$/\1/;')") yann@850: yann@850: case "${CT_THREADS}" in yann@1478: nptl) extra_config+=("--with-__thread" "--with-tls");; yann@1478: linuxthreads) extra_config+=("--with-__thread" "--without-tls" "--without-nptl");; yann@1478: none) extra_config+=("--without-__thread" "--without-nptl") yann@850: case "${CT_LIBC_GLIBC_EXTRA_CONFIG}" in yann@850: *-tls*) ;; yann@1478: *) extra_config+=("--without-tls");; yann@850: esac yann@850: ;; yann@850: esac yann@850: yann@850: case "${CT_SHARED_LIBS}" in yann@1478: y) extra_config+=("--enable-shared");; yann@1478: *) extra_config+=("--disable-shared");; yann@850: esac yann@850: yann@850: case "${CT_ARCH_FLOAT_HW},${CT_ARCH_FLOAT_SW}" in yann@1478: y,) extra_config+=("--with-fp");; yann@1478: ,y) extra_config+=("--without-fp");; yann@850: esac yann@850: yann@850: case "$(do_libc_add_ons_list ,)" in yann@850: "") ;; yann@1478: *) extra_config+=("--enable-add-ons=$(do_libc_add_ons_list ,)");; yann@850: esac yann@850: yann@850: extra_cc_args="${extra_cc_args} ${CT_ARCH_ENDIAN_OPT}" yann@850: yann@850: cross_cc=$(CT_Which "${CT_TARGET}-gcc") yann@850: yann@850: CT_DoLog DEBUG "Using gcc for target: '${cross_cc}'" yann@850: CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'" yann@1478: CT_DoLog DEBUG "Extra config args passed: '${extra_config[*]}'" yann@850: CT_DoLog DEBUG "Extra CC args passed : '${extra_cc_args}'" yann@850: yann@1041: BUILD_CC="${CT_BUILD}-gcc" \ yann@1552: CFLAGS="${CT_TARGET_CFLAGS} ${CT_LIBC_GLIBC_EXTRA_CFLAGS} -O2" \ yann@850: CC="${CT_TARGET}-gcc ${CT_LIBC_EXTRA_CC_ARGS} ${extra_cc_args}" \ yann@850: AR=${CT_TARGET}-ar \ yann@850: RANLIB=${CT_TARGET}-ranlib \ yann@850: CT_DoExecLog ALL \ yann@1123: "${CT_SRC_DIR}/eglibc-${CT_LIBC_VERSION}/configure" \ yann@850: --prefix=/usr \ yann@850: --with-headers="${CT_HEADERS_DIR}" \ yann@1041: --build=${CT_BUILD} \ yann@850: --host=${CT_TARGET} \ yann@850: --disable-profile \ yann@850: --without-gd \ yann@850: --without-cvs \ yann@1478: "${extra_config[@]}" \ yann@850: ${CT_LIBC_GLIBC_EXTRA_CONFIG} yann@850: yann@850: CT_DoLog EXTRA "Building C library" yann@850: yann@1328: # eglibc build hacks yann@1328: # http://sourceware.org/ml/crossgcc/2008-10/msg00068.html yann@1328: case "${CT_ARCH},${CT_ARCH_CPU}" in yann@1328: powerpc,8??) yann@1328: CT_DoLog DEBUG "Activating support for memset on broken ppc-8xx (CPU15 erratum)" yann@1328: EGLIBC_BUILD_ASFLAGS="-DBROKEN_PPC_8xx_CPU15";; yann@1328: esac yann@1328: yann@1328: CT_DoExecLog ALL make ASFLAGS="${EGLIBC_BUILD_ASFLAGS}" yann@850: yann@850: CT_DoLog EXTRA "Installing C library" yann@850: yann@850: CT_DoExecLog ALL make install install_root="${CT_SYSROOT_DIR}" yann@850: yann@850: CT_EndStep yann@850: } yann@850: yann@850: # This function finishes the glibc install yann@850: do_libc_finish() { yann@850: # Nothing to be done for eglibc yann@850: : yann@850: } yann@850: yann@850: # Build up the addons list, separated with $1 yann@850: do_libc_add_ons_list() { yann@850: local sep="$1" yann@850: local addons_list=$(echo "${CT_LIBC_ADDONS_LIST//,/${sep}}" |tr -s ,) yann@850: case "${CT_THREADS}" in yann@850: none) ;; yann@850: *) addons_list="${addons_list}${sep}${CT_THREADS}";; yann@850: esac yann@850: [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && addons_list="${addons_list}${sep}ports" yann@850: addons_list="${addons_list%%${sep}}" yann@850: echo "${addons_list##${sep}}" yann@850: }