Alexey Neyman 93be629f2b Fold libc_start_files into libc
After 557b9d4, libc_start_files and libc_main steps are performed one
after another. It doesn't make sense, especially since some of the libcs
(glibc, uClibc-ng) go to great lengths to first install start files in
the first step, libc_start_files, only to remove them immediately in the
second step, libc_main.

Current build steps also break in the xtensa newlib configurations, as
it needs to install the custom xtensa headers before building the libgcc
and after 557b9d4, the headers are not installed before libgcc is built
in pass-1.

Therefore, finish what 557b9d4 mentioned but did not do: move header
installation into a new step, libc_headers, and combine libc_start_files
and libc_main into a single step.

This also allows to combine the core pass-1/pass-2 steps, to be done in
a subsequent commit.

Signed-off-by: Alexey Neyman <stilor@att.net>
2022-02-11 00:47:51 -08:00

341 lines
14 KiB
Bash

# This file declares functions to install the uClibc C library
# Copyright 2007 Yann E. MORIN
# Licensed under the GPL v2. See COPYING in the root of this package
# This function builds and install the full C library
uClibc_ng_main()
{
CT_DoStep INFO "Installing C library"
CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc"
CT_IterateMultilibs uClibc_ng_backend_once multilib
CT_Popd
CT_EndStep
}
# Common backend for 1st and 2nd passes, once per multilib.
uClibc_ng_backend_once()
{
local multi_dir multi_os_dir multi_root multi_flags multi_index multi_count
local multilib_dir startfiles_dir
local jflag=${CT_JOBSFLAGS}
local -a make_args
local extra_cflags f cfg_cflags cf
local hdr_install_subdir
for arg in "$@"; do
eval "${arg// /\\ }"
done
CT_DoStep INFO "Building for multilib ${multi_index}/${multi_count}: '${multi_flags}'"
multilib_dir="lib/${multi_os_dir}"
startfiles_dir="${multi_root}/usr/${multilib_dir}"
CT_SanitizeVarDir multilib_dir startfiles_dir
# Construct make arguments:
# - uClibc uses the CROSS environment variable as a prefix to the compiler
# tools to use. Since it requires core pass-1, thusly named compiler is
# already available.
# - Note about CFLAGS: In uClibc, CFLAGS are generated by Rules.mak,
# depending on the configuration of the library. That is, they are tailored
# to best fit the target. So it is useless and seems to be a bad thing to
# use LIBC_EXTRA_CFLAGS here.
# - We do _not_ want to strip anything for now, in case we specifically
# asked for a debug toolchain, thus the STRIPTOOL= assignment.
make_args=( CROSS_COMPILE="${CT_TARGET}-" \
HOSTCC="${CT_BUILD}-gcc" \
PREFIX="${multi_root}/" \
MULTILIB_DIR="${multilib_dir}" \
STRIPTOOL=true \
${CT_LIBC_UCLIBC_VERBOSITY} \
)
# Simply copy files until uClibc has the ability to build out-of-tree
CT_DoLog EXTRA "Copying sources to build dir"
CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/uClibc-ng/." .
# Force the date of the pregen locale data, as the
# newer ones that are referenced are not available
CT_DoLog EXTRA "Applying configuration"
# Use the default config if the user did not provide one.
if [ -z "${CT_LIBC_UCLIBC_CONFIG_FILE}" ]; then
CT_LIBC_UCLIBC_CONFIG_FILE="${CT_LIB_DIR}/packages/uClibc-ng/config"
fi
manage_uClibc_config "${CT_LIBC_UCLIBC_CONFIG_FILE}" .config "${multi_flags}"
CT_DoExecLog ALL make "${make_args[@]}" olddefconfig
# Now filter the multilib flags. manage_uClibc_config did the opposite of
# what Rules.mak in uClibc would do: by the multilib's CFLAGS, it determined
# the applicable configuration options. We don't want to pass the same options
# in the UCLIBC_EXTRA_CFLAGS again (on some targets, the options do not correctly
# override each other). On the other hand, we do not want to lose the options
# that are not reflected in the .config.
extra_cflags="-pipe"
{ echo "include Rules.mak"; echo "show-cpu-flags:"; printf '\t@echo $(CPU_CFLAGS)\n'; } \
> .show-cpu-cflags.mk
cfg_cflags=$( make "${make_args[@]}" \
--no-print-directory -f .show-cpu-cflags.mk show-cpu-flags )
CT_DoExecLog ALL rm -f .show-cpu-cflags.mk
CT_DoLog DEBUG "CPU_CFLAGS detected by uClibc: ${cfg_cflags[@]}"
for f in ${multi_flags}; do
for cf in ${cfg_cflags}; do
if [ "${f}" = "${cf}" ]; then
f=
break
fi
done
if [ -n "${f}" ]; then
extra_cflags+=" ${f}"
fi
done
CT_DoLog DEBUG "Filtered multilib CFLAGS: ${extra_cflags}"
make_args+=( UCLIBC_EXTRA_CFLAGS="${extra_cflags}" )
# uClibc does not have a way to select the installation subdirectory for headers,
# it is always $(DEVEL_PREFIX)/include. Also, we're reinstalling the headers
# at the final stage (see the note below), we may already have the subdirectory
# in /usr/include.
CT_DoArchUClibcHeaderDir hdr_install_subdir "${multi_flags}"
if [ -n "${hdr_install_subdir}" ]; then
CT_DoExecLog ALL cp -a "${multi_root}/usr/include" "${multi_root}/usr/include.saved"
fi
CT_DoLog EXTRA "Building C library"
CT_DoExecLog ALL make "${make_args[@]}" pregen
CT_DoExecLog ALL make ${jflag} "${make_args[@]}" all
CT_DoLog EXTRA "Installing C library"
CT_DoExecLog ALL make "${make_args[@]}" install install_utils
# Now, if installing headers into a subdirectory, put everything in its place.
# Remove the header subdirectory if it existed already.
if [ -n "${hdr_install_subdir}" ]; then
CT_DoExecLog ALL mv "${multi_root}/usr/include" "${multi_root}/usr/include.new"
CT_DoExecLog ALL mv "${multi_root}/usr/include.saved" "${multi_root}/usr/include"
CT_DoExecLog ALL rm -rf "${multi_root}/usr/include/${hdr_install_subdir}"
CT_DoExecLog ALL mv "${multi_root}/usr/include.new" "${multi_root}/usr/include/${hdr_install_subdir}"
fi
CT_EndStep
}
# Initialises the .config file to sensible values
# $1: original file
# $2: modified file
manage_uClibc_config()
{
src="$1"
dst="$2"
flags="$3"
# Start with fresh files
CT_DoExecLog ALL cp "${src}" "${dst}"
case "${CT_ARCH_ENDIAN}" in
big|big,little)
CT_KconfigDisableOption "ARCH_LITTLE_ENDIAN" "${dst}"
CT_KconfigDisableOption "ARCH_WANTS_LITTLE_ENDIAN" "${dst}"
CT_KconfigEnableOption "ARCH_BIG_ENDIAN" "${dst}"
CT_KconfigEnableOption "ARCH_WANTS_BIG_ENDIAN" "${dst}"
;;
little|little,big)
CT_KconfigDisableOption "ARCH_BIG_ENDIAN" "${dst}"
CT_KconfigDisableOption "ARCH_WANTS_BIG_ENDIAN" "${dst}"
CT_KconfigEnableOption "ARCH_LITTLE_ENDIAN" "${dst}"
CT_KconfigEnableOption "ARCH_WANTS_LITTLE_ENDIAN" "${dst}"
;;
esac
if [ "${CT_ARCH_USE_MMU}" = "y" ]; then
CT_KconfigEnableOption "ARCH_USE_MMU" "${dst}"
else
CT_KconfigDisableOption "ARCH_USE_MMU" "${dst}"
CT_KconfigDisableOption "UCLIBC_FORMAT_FDPIC" "${dst}"
CT_KconfigDisableOption "UCLIBC_FORMAT_FLAT" "${dst}"
CT_KconfigDisableOption "UCLIBC_FORMAT_SHARED_FLAT" "${dst}"
case "${CT_ARCH_BINFMT_FLAT},${CT_ARCH_BINFMT_FDPIC},${CT_SHARED_LIBS}" in
y,,y) CT_KconfigEnableOption "UCLIBC_FORMAT_SHARED_FLAT" "${dst}";;
y,,) CT_KconfigEnableOption "UCLIBC_FORMAT_FLAT" "${dst}";;
,y,*) CT_KconfigEnableOption "UCLIBC_FORMAT_FDPIC" "${dst}";;
*) CT_Abort "Unsupported binary format";;
esac
fi
if [ "${CT_SHARED_LIBS}" = "y" ]; then
CT_KconfigEnableOption "HAVE_SHARED" "${dst}"
else
CT_KconfigDisableOption "HAVE_SHARED" "${dst}"
fi
# Accomodate for old and new uClibc version, where the
# way to select between hard/soft float has changed
case "${CT_ARCH_FLOAT}" in
hard|softfp)
CT_KconfigEnableOption "UCLIBC_HAS_FPU" "${dst}"
CT_KconfigEnableOption "UCLIBC_HAS_FLOATS" "${dst}"
;;
soft)
CT_KconfigDisableOption "UCLIBC_HAS_FPU" "${dst}"
CT_KconfigEnableOption "UCLIBC_HAS_FLOATS" "${dst}"
CT_KconfigEnableOption "DO_C99_MATH" "${dst}"
;;
esac
if [ "${CT_LIBC_UCLIBC_FENV}" = "y" ]; then
CT_KconfigEnableOption "UCLIBC_HAS_FENV" "${dst}"
else
CT_KconfigDisableOption "UCLIBC_HAS_FENV" "${dst}"
fi
if [ "${CT_LIBC_UCLIBC_RPC}" = "y" ]; then
CT_KconfigEnableOption "UCLIBC_HAS_RPC" "${dst}"
else
CT_KconfigDisableOption "UCLIBC_HAS_RPC" "${dst}"
fi
# We always want ctor/dtor
CT_KconfigEnableOption "UCLIBC_CTOR_DTOR" "${dst}"
# Change paths to work with crosstool-NG
#
# DEVEL_PREFIX is left as '/usr/' because it is post-pended to $PREFIX,
# which is the correct value of ${PREFIX}/${TARGET}.
CT_KconfigSetOption "DEVEL_PREFIX" "\"/usr/\"" "${dst}"
CT_KconfigSetOption "RUNTIME_PREFIX" "\"/\"" "${dst}"
CT_KconfigSetOption "KERNEL_HEADERS" "\"${CT_HEADERS_DIR}\"" "${dst}"
# Locales support
# Note that the two PREGEN_LOCALE and the XLOCALE lines may be missing
# entirely if LOCALE is not set. If LOCALE was already set, we'll
# assume the user has already made all the appropriate generation
# arrangements. Note that having the uClibc Makefile download the
# pregenerated locales is not compatible with crosstool.
if [ -z "${CT_LIBC_UCLIBC_LOCALES}" ]; then
CT_KconfigDisableOption "UCLIBC_HAS_LOCALE" "${dst}"
else
CT_KconfigEnableOption "UCLIBC_HAS_LOCALE" "${dst}"
CT_KconfigDeleteOption "UCLIBC_PREGENERATED_LOCALE_DATA" "${dst}"
CT_KconfigDeleteOption "UCLIBC_DOWNLOAD_PREGENERATED_LOCALE_DATA" "${dst}"
fi
# WCHAR support
if [ "${CT_LIBC_UCLIBC_WCHAR}" = "y" ]; then
CT_KconfigEnableOption "UCLIBC_HAS_WCHAR" "${dst}"
else
CT_KconfigDisableOption "UCLIBC_HAS_WCHAR" "${dst}"
fi
# IPv6 support
if [ "${CT_LIBC_UCLIBC_IPV6}" = "y" ]; then
CT_KconfigEnableOption "UCLIBC_HAS_IPV6" "${dst}"
else
CT_KconfigDisableOption "UCLIBC_HAS_IPV6" "${dst}"
fi
# Iconv support
if [ "${CT_LIBC_UCLIBC_LIBICONV}" = "y" ]; then
CT_KconfigEnableOption "UCLIBC_HAS_LIBICONV" "${dst}"
else
CT_KconfigDisableOption "UCLIBC_HAS_LIBICONV" "${dst}"
fi
# Force on options needed for C++ if we'll be making a C++ compiler.
# I'm not sure locales are a requirement for doing C++... Are they?
if [ "${CT_CC_LANG_CXX}" = "y" ]; then
CT_KconfigEnableOption "DO_C99_MATH" "${dst}"
CT_KconfigEnableOption "UCLIBC_HAS_GNU_GETOPT" "${dst}"
fi
# Stack Smash Protection (SSP)
if [ "${CT_LIBC_UCLIBC_HAS_SSP}" = "y" ]; then
CT_KconfigEnableOption "UCLIBC_HAS_SSP" "${dst}"
else
CT_KconfigDisableOption "UCLIBC_HAS_SSP" "${dst}"
fi
if [ "${CT_LIBC_UCLIBC_BUILD_SSP}" = "y" ]; then
CT_KconfigEnableOption "UCLIBC_BUILD_SSP" "${dst}"
else
CT_KconfigDisableOption "UCLIBC_BUILD_SSP" "${dst}"
fi
# Push the threading model
CT_KconfigDisableOption "UCLIBC_HAS_THREADS" "${dst}"
CT_KconfigDisableOption "LINUXTHREADS_OLD" "${dst}"
CT_KconfigDisableOption "LINUXTHREADS_NEW" "${dst}"
CT_KconfigDisableOption "UCLIBC_HAS_THREADS_NATIVE" "${dst}"
case "${CT_THREADS}" in
none)
;;
linuxthreads)
CT_KconfigEnableOption "UCLIBC_HAS_THREADS" "${dst}"
CT_KconfigEnableOption "UCLIBC_HAS_LINUXTHREADS" "${dst}"
;;
nptl)
CT_KconfigEnableOption "UCLIBC_HAS_THREADS" "${dst}"
CT_KconfigEnableOption "UCLIBC_HAS_THREADS_NATIVE" "${dst}"
;;
*)
CT_Abort "Incorrect thread settings: CT_THREADS='${CT_THREADS}'"
;;
esac
# Always build the libpthread_db
CT_KconfigEnableOption "PTHREADS_DEBUG_SUPPORT" "${dst}"
# Force on debug options if asked for
CT_KconfigDisableOption "DODEBUG" "${dst}"
CT_KconfigDisableOption "DODEBUG_PT" "${dst}"
CT_KconfigDisableOption "DOASSERTS" "${dst}"
CT_KconfigDisableOption "SUPPORT_LD_DEBUG" "${dst}"
CT_KconfigDisableOption "SUPPORT_LD_DEBUG_EARLY" "${dst}"
CT_KconfigDisableOption "UCLIBC_MALLOC_DEBUGGING" "${dst}"
case "${CT_LIBC_UCLIBC_DEBUG_LEVEL}" in
0)
;;
1)
CT_KconfigEnableOption "DODEBUG" "${dst}"
;;
2)
CT_KconfigEnableOption "DODEBUG" "${dst}"
CT_KconfigEnableOption "DOASSERTS" "${dst}"
CT_KconfigEnableOption "SUPPORT_LD_DEBUG" "${dst}"
CT_KconfigEnableOption "UCLIBC_MALLOC_DEBUGGING" "${dst}"
;;
3)
CT_KconfigEnableOption "DODEBUG" "${dst}"
CT_KconfigEnableOption "DODEBUG_PT" "${dst}"
CT_KconfigEnableOption "DOASSERTS" "${dst}"
CT_KconfigEnableOption "SUPPORT_LD_DEBUG" "${dst}"
CT_KconfigEnableOption "SUPPORT_LD_DEBUG_EARLY" "${dst}"
CT_KconfigEnableOption "UCLIBC_MALLOC_DEBUGGING" "${dst}"
;;
esac
# Remove stripping: its the responsibility of the
# firmware builder to strip or not.
CT_KconfigDisableOption "DOSTRIP" "${dst}"
# Now allow architecture to tweak as it wants
CT_DoArchUClibcConfig "${dst}"
CT_DoArchUClibcCflags "${dst}" "${flags}"
# Preserve the config we created (before uclibc's `make olddefconfig`
# overrides anything).
CT_DoExecLog ALL cp "${dst}" "${dst}.created-by-ct-ng"
}
uClibc_ng_post_cc()
{
# uClibc and GCC disagree where the dynamic linker lives. uClibc always
# places it in the MULTILIB_DIR, while gcc does that for *some* variants
# and expects it in /lib for the other. So, create a symlink from lib
# to the actual location, but only if that will not override the actual
# file in /lib. Thus, need to do this after all the variants are built.
# Moreover, need to do this after the final compiler is built: on targets
# that use elf2flt, the core compilers cannot find ld when running elf2flt.
CT_MultilibFixupLDSO
if [ -n "${CT_LIBC_UCLIBC_CONFIG_FILE}" ]; then
CT_InstallConfigurationFile "${CT_LIBC_UCLIBC_CONFIG_FILE}" libc
fi
}