You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
10 KiB

# Copyright 1999-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
EAPI="6"
inherit flag-o-matic multilib savedconfig toolchain-funcs versionator
if [[ ${PV} == "9999" ]] ; then
EGIT_REPO_URI="git://uclibc-ng.org/git/uclibc-ng"
inherit git-r3
MY_P=uclibc-ng-${PV}
else
MY_P=uClibc-ng-${PV}
fi
DESCRIPTION="C library for developing embedded Linux systems"
HOMEPAGE="https://uclibc-ng.org/"
if [[ ${PV} != "9999" ]] ; then
PATCH_VER=""
SRC_URI="https://downloads.uclibc-ng.org/releases/${PV}/${MY_P}.tar.bz2"
KEYWORDS="-* ~amd64 ~arm ~mips ~ppc ~x86"
fi
LICENSE="LGPL-2"
SLOT="0"
IUSE="debug hardened iconv ipv6 symlink-compat headers-only"
RESTRICT="strip"
# 1) We can't upgrade from uclibc to uclibc-ng via a soft blocker since portage
# will delete the ld.so sym link prematurely and break the system. So we
# will hard block and give manual migration instructions.
# 2) Currently uclibc and uclibc-ng's iconv are in bad shape. We've been using
# the breakout library. The disadvantage here is that we have to sprinkle
# LDFAGS=-liconv on build systems that need to link against libiconv.
RDEPEND="
!!sys-libs/uclibc
iconv? ( dev-libs/libiconv )"
S=${WORKDIR}/${MY_P}
export CBUILD=${CBUILD:-${CHOST}}
export CTARGET=${CTARGET:-${CHOST}}
if [[ ${CHOST} == ${CTARGET} ]] ; then
if [[ ${CATEGORY} == cross-* ]] ; then
export CTARGET=${CATEGORY#cross-}
fi
fi
is_crosscompile() {
[[ ${CHOST} != ${CTARGET} ]]
}
alt_build_kprefix() {
if [[ ${CBUILD} == ${CHOST} && ${CHOST} == ${CTARGET} ]] ; then
echo /usr/include
else
echo /usr/${CTARGET}/usr/include
fi
}
just_headers() {
use headers-only && is_crosscompile
}
uclibc_endian() {
# XXX: this wont work for a toolchain which is bi-endian, but we
# dont have any such thing at the moment, so not a big deal
touch "${T}"/endian.s
$(tc-getAS ${CTARGET}) "${T}"/endian.s -o "${T}"/endian.o
case $(file "${T}"/endian.o) in
*" MSB "*) echo "BIG";;
*" LSB "*) echo "LITTLE";;
*) echo "NFC";;
esac
rm -f "${T}"/endian.{s,o}
}
kconfig_q_opt() {
local flag=$1; shift
case ${flag} in
y|n) ;;
*) flag=$(usex ${flag} y n) ;;
esac
local var="defs_${flag}"
eval "${var}+=( $* )"
}
get_opt() {
(
unset ${1}
. ${2:-"${S}"/.config}
echo ${!1}
)
}
make_oldconfig() {
yes "" 2>/dev/null | emake -s oldconfig >/dev/null
}
make_config() {
restore_config .config
if [ -f .config ]; then
make_oldconfig
return 0
else
ewarn "Could not locate user configfile, so we will save a default one"
fi
emake ARCH=$1 defconfig >/dev/null
local defs_{y,n}
# These are forced off
defs_n=(
DOASSERTS
DODEBUG_PT
HAS_NO_THREADS
PROPOLICE_BLOCK_ABRT
SSP_QUICK_CANARY
SUPPORT_LD_DEBUG_EARLY
UCLIBC_HAS_CTYPE_UNSAFE
UCLIBC_HAS_LOCALE
LDSO_SAFE_RUNPATH
)
# These are forced on
defs_y=(
DO_C99_MATH
DO_XSI_MATH
FORCE_SHAREABLE_TEXT_SEGMENTS
LDSO_GNU_HASH_SUPPORT
LDSO_PRELOAD_FILE_SUPPORT
LDSO_RUNPATH
LDSO_RUNPATH_OF_EXECUTABLE
LDSO_STANDALONE_SUPPORT
PROPOLICE_BLOCK_SEGV
PTHREADS_DEBUG_SUPPORT
UCLIBC_HAS_ARC4RANDOM
UCLIBC_HAS_BACKTRACE
UCLIBC_HAS_BSD_RES_CLOSE
UCLIBC_HAS_CONTEXT_FUNCS
UCLIBC_HAS_CTYPE_CHECKED
UCLIBC_HAS_EXTRA_COMPAT_RES_STATE
UCLIBC_HAS_FENV
UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE
UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE
UCLIBC_HAS_FOPEN_LARGEFILE_MODE
UCLIBC_HAS_FTS
UCLIBC_HAS_FTW
UCLIBC_HAS_GETPT
UCLIBC_HAS_GLIBC_CUSTOM_PRINTF
UCLIBC_HAS_GLIBC_CUSTOM_STREAMS
UCLIBC_HAS_GNU_GLOB
UCLIBC_HAS_HEXADECIMAL_FLOATS
UCLIBC_HAS_LIBUTIL
UCLIBC_HAS_NFTW
UCLIBC_HAS_OBSOLETE_BSD_SIGNAL
UCLIBC_HAS_PRINTF_M_SPEC
UCLIBC_HAS_PROGRAM_INVOCATION_NAME
UCLIBC_HAS_RESOLVER_SUPPORT
UCLIBC_HAS_SHA256_CRYPT_IMPL
UCLIBC_HAS_SHA512_CRYPT_IMPL
UCLIBC_HAS_SSP
UCLIBC_HAS_STUBS
UCLIBC_HAS_SYS_ERRLIST
UCLIBC_HAS_SYS_SIGLIST
UCLIBC_HAS_THREADS_NATIVE
UCLIBC_HAS_TZ_FILE_READ_MANY
UCLIBC_HAS_UTMP
UCLIBC_HAS_UTMPX
UCLIBC_HAS_WCHAR
UCLIBC_HAS_WORDEXP
UCLIBC_NTP_LEGACY
UCLIBC_SUPPORT_AI_ADDRCONFIG
UCLIBC_SUSV2_LEGACY
UCLIBC_SUSV3_LEGACY
UCLIBC_SUSV3_LEGACY_MACROS
UCLIBC_SUSV4_LEGACY
UCLIBC_USE_NETLINK
)
sed -i -e '/ARCH_.*_ENDIAN/d' .config
kconfig_q_opt y "ARCH_WANTS_$(uclibc_endian)_ENDIAN"
kconfig_q_opt debug DODEBUG
kconfig_q_opt debug SUPPORT_LD_DEBUG
kconfig_q_opt debug UCLIBC_HAS_PROFILING
kconfig_q_opt ipv6 UCLIBC_HAS_IPV6
kconfig_q_opt hardened UCLIBC_BUILD_NOEXECSTACK
kconfig_q_opt hardened UCLIBC_BUILD_NOW
kconfig_q_opt hardened UCLIBC_BUILD_PIE
kconfig_q_opt hardened UCLIBC_BUILD_RELRO
kconfig_q_opt hardened UCLIBC_BUILD_SSP
local count def
for count in 1 2 ; do
# Run twice as some config opts depend on others being enabled first.
for def in ${defs_y[@]} ; do
sed -i -e "s|.*\<${def}\>.*set|${def}=y|g" .config
done
for def in ${defs_n[@]} ; do
sed -i -e "s|${def}=y|# ${def} is not set|g" .config
done
make_oldconfig
done
einfo "Enabled options:"
for def in ${defs_y[@]} ; do
einfo " " $(grep "^${def}=y" .config || echo "could not find ${def}")
done
einfo "Disabled options:"
for def in ${defs_n[@]} ; do
einfo " " $(grep "^# ${def} is not set" .config || echo "could not find ${def}")
done
# setup build and run paths
sed -i \
-e "/^CROSS_COMPILER_PREFIX/s|=.*|=\"${CTARGET}-\"|" \
-e "/^KERNEL_HEADERS/s|=.*|=\"$(alt_build_kprefix)\"|" \
-e "/^SHARED_LIB_LOADER_PREFIX/s|=.*|=\"/$(get_libdir)\"|" \
-e "/^DEVEL_PREFIX/s|=.*|=\"/usr\"|" \
-e "/^RUNTIME_PREFIX/s|=.*|=\"/\"|" \
-e "/^UCLIBC_EXTRA_CFLAGS/s|=.*|=\"${UCLIBC_EXTRA_CFLAGS}\"|" \
.config || die
make_oldconfig
}
pkg_setup() {
# Make sure our CHOST is a uclibc toolchain for native compiling
if [[ ${CHOST} == ${CTARGET} ]]; then
case ${CHOST} in
*-uclinux*|*-uclibc*) ;;
*) die "Use sys-devel/crossdev to build a uclibc toolchain" ;;
esac
fi
# uClibc-ng doesn't carry old Linux threads, and since we force
# threading our only choice is NPTL which requires i486 and later.
[[ ${CTARGET} == i386* ]] && die "i386 can't support Native Posix Threads (NPTL)."
}
src_prepare() {
local version subversion extraversion
# uclibc-ng tries to create a two sym link with ld.so,
# ld-uClibc.so.{0,MAJOR_VERSION} -> ld-uClibc-<version>.so
# where MAJOR_VERSION != 0 indicates the ABI verison.
# We want to get rid of this and just have ABI = 0.
eapply "${FILESDIR}"/uclibc-compat-r1.patch
# We need to change the major.minor.sublevel of uclibc-ng.
# Upstream sets MAJOR_VERSION = 1 which breaks runtime linking.
# If we really want the ABI bump, we'll have to hack the gcc
# spec file and change the '*link:' rule.
version=( $(get_version_components) )
if [[ -z ${version[1]} ]]; then
subversion=0
extraversion=0
else
subversion=${version[1]}
if [[ -z ${version[2]} ]]; then
extraversion=0
else
extraversion=.${version[2]}
fi
fi
sed -i \
-e "/^MAJOR_VERSION/s|:=.*|:= 0|" \
-e "/^MINOR_VERSION/s|:=.*|:= ${version[0]}|" \
-e "/^SUBLEVEL/s|:=.*|:= ${subversion}|" \
-e "/^EXTRAVERSION/s|:=.*|:= ${extraversion}|" \
Rules.mak || die
eapply_user
}
src_configure() {
# Map our toolchain arch name to the name expected by uClibc-ng.
local target=$(tc-arch)
case ${target} in
amd64) target="x86_64";;
arm) target="arm";;
mips) target="mips";;
ppc) target="powerpc";;
x86) target="i386";;
esac
# Do arch specific configuration by changing the defaults in
# extra/Configs/Config.<arch>. If these are not overridden
# by an save .config, they will be selected by default.
# For i386, i486, i586 and i686
local cpu
if [[ ${target} == "i386" ]]; then
[[ ${CTARGET} == i[456]86* ]] && cpu="${CTARGET:1:1}86"
sed -i -e "s|default CONFIG_686|default CONFIG_${cpu:-486}|" \
extra/Configs/Config.i386 || die
fi
# For arm
if [[ ${target} == "arm" ]]; then
sed -i -e '/Build for EABI/a \\tdefault y' extra/Configs/Config.arm
fi
# We set HOSTCC to the proper tuple rather than just 'gcc'
sed -i -e "s|^HOSTCC.*=.*|HOSTCC=$(tc-getBUILD_CC)|" Rules.mak
make_config ${target}
einfo
einfo "Runtime Prefix: /"
einfo "Devel Prefix: /usr"
einfo "Kernel Prefix: $(alt_build_kprefix)"
einfo "CBUILD: ${CBUILD}"
einfo "CHOST: ${CHOST}"
einfo "CTARGET: ${CTARGET}"
einfo "ABI: ${ABI}"
einfo "ENDIAN: $(uclibc_endian)"
einfo
}
src_compile() {
emake headers
just_headers && return 0
emake
if is_crosscompile ; then
emake -C utils hostutils
else
emake utils
fi
}
src_test() {
is_crosscompile && return 0
# assert test fails on pax/grsec enabled kernels
# normal vfork test fails in sandbox (both glibc/uclibc)
emake UCLIBC_ONLY=1 check
}
src_install() {
local sysroot=${D}
is_crosscompile && sysroot+="/usr/${CTARGET}"
local target="install"
just_headers && target="install_headers"
emake DESTDIR="${sysroot}" ${target}
save_config .config
# remove files coming from kernel-headers
rm -rf "${sysroot}"/usr/include/{linux,asm*}
# Make sure we install the sys-include symlink so that when
# we build a 2nd stage cross-compiler, gcc finds the target
# system headers correctly. See gcc/doc/gccinstall.info
if is_crosscompile ; then
dosym usr/include /usr/${CTARGET}/sys-include
if ! just_headers && [[ -n $(get_opt HAVE_SHARED) ]] ; then
newbin utils/ldconfig.host ${CTARGET}-ldconfig
newbin utils/ldd.host ${CTARGET}-ldd
fi
return 0
fi
if use symlink-compat; then
dosym libc.so.0 "${DESTDIR}"/lib/libcrypt.so.0
dosym libc.so.0 "${DESTDIR}"/lib/libdl.so.0
dosym libc.so.0 "${DESTDIR}"/lib/libm.so.0
dosym libc.so.0 "${DESTDIR}"/lib/libpthread.so.0
dosym libc.so.0 "${DESTDIR}"/lib/librt.so.0
dosym libc.so.0 "${DESTDIR}"/lib/libresolv.so.0
dosym libc.so.0 "${DESTDIR}"/lib/libubacktrace.so.0
dosym libc.so.0 "${DESTDIR}"/lib/libutil.so.0
fi
emake DESTDIR="${D}" install_utils
dobin extra/scripts/getent
dodoc README docs/*.txt
}
pkg_postinst() {
is_crosscompile && return 0
if [ ! -e "${ROOT}"/etc/TZ ] ; then
ewarn "Please remember to set your timezone in /etc/TZ"
mkdir -p "${ROOT}"/etc
echo "UTC" > "${ROOT}"/etc/TZ
fi
[ "${ROOT}" != "/" ] && return 0
# update cache before reloading init
ldconfig
# reload init ...
/sbin/telinit U 2>/dev/null
}