Derick Swanepoel wrote:

Hi,

I'm busy building a cross-compile environment for an ARM (XScale) in an x86
host environment, but I'm having trouble emerging packages like procps and
gdb which require headers from /usr/include.
What do you need procps for? If you're using busybox, it already contains ps, free, top and kill and it should be enough for most embedded systems.

I've built an armeb-softfloat-linux-uclibc cross toolchain with crossdev
which can successfully compile uclibc, bash, baselayout, etc. and install
in ROOT=/gentoo-arm. However, when I try to emerge something like procps,
it fails to find curses.h and termcap.h. Where should the cross-compiler be
looking for these headers?
Is ROOT the only variable you set? There are some other important vars, like ARCH, CBUILD, CHOST, CTARGET. Many others are also useful while cross-emerging.

Another problem I have is that gawk (3.1.4-r4) fails to execute with:
awk: can't resolve symbol '__fixdfsi'
As far as I can determine, __fixdfsi is one of GCC's softfloat library routines.

I would really like to know how the armeb-uclibc-softfloat stages (found in
experimental/arm/embedded on various Gentoo mirrors) were built.
As far as I know, they use catalyst.

Thanks,
Derick

I am building small Embedded Gentoo systems for i686 and ARM920T architectures and for that I wrote a little script called egg (attached). Perhaps you will find it useful. To create such a system for arm920t (baselayout+uclibc+busybox), I'd simply run:

# crossdev -t arm-unknown-linux-uclibc
# egg -l uclibc -a arm920t -o /home/gentoo-for-arm

Later, to add some packages (e.g. dropbear and ncurses) I'd write:

# egg -l uclibc -a arm920t -o /home/gentoo-for-arm -fn dropbear ncurses

And finally, when I'm satisfied with my rootfs, I can strip it off unnecessary trash:

# egg -l uclibc -arm920t -o /home/gentoo-for-arm -fns

This is an extremely simple tool (e.g. you can't set USE flags for individual packages), but still I find it quite sufficient for my work. You can use it to generate a rootfs for an armeb architecture just by adding it to parse_arch() function. If you do that, don't forget to send me the updated version.

Hope you find it useful,
Stanislaw Raczynski
#!/bin/bash
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# 
# This script creates a tiny rootfs intended for embedded
# systems. It consists of baselayout, a C library, system tools
# and optional user packages.
#
# Created by Stanislaw Raczynski (sutashu at gmail dot com)
#
# Written by Stanislaw Raczynski (sutashu at gmail dot com),
#            Marek Malczak

#-----------------------------------------------------------------------------
source /sbin/functions.sh || exit 3
if [[ `whoami` != "root" ]] ; then
        eerror "You must run this as root"
        exit 2
fi
#-----------------------------------------------------------------------------
die() {
        echo
        eerror $*
        eerror Please read the logfiles:
        eerror ${PORT_LOGDIR}/mkrootfs.log
        eerror ${logfile}
        exit 1
}
#-----------------------------------------------------------------------------
# Far out of date
usage() {
cat << EOF
Usage: ${HILITE}egg${NORMAL} ${GOOD}[options]${NORMAL}
${GOOD}[extra packages]${NORMAL}
Options:
${GOOD}-l${NORMAL} libc
Specify variant of libc to use. See egg -l help for details.
${GOOD}-b${NORMAL} baselayout
Specify variant of baselayout to use. See egg -b help for details.
${GOOD}-u${NORMAL} utils
Specify variant of system tools to use. See egg -u help for details.
${GOOD}-a${NORMAL} arch
Specify target architecture.
${GOOD}-s${NORMAL}
Strip rootfs at the end.
${GOOD}-v${NORMAL}
Be verbose.
EOF
exit ${1:-0}
}
#-----------------------------------------------------------------------------
parse_arch() {
CROSS_COMPILING="yes"
case $1 in
        help) cat << EOF

Supported architectures for cross-compiling:
${GOOD}arm{$NORMAL} Generic ARM
${GOOD}arm920t{$NORMAL} ARM 920t
${GOOD}x86{$NORMAL} Generic x86
EOF
           exit 0;;
        arm) TARCH="arm";
             EKEYWORDS="-* arm";
             ECHOST="arm-unknown-linux-";
             EUCLIBC_CPU="GENERIC_ARM";;
        arm920t) TARCH="arm";
                 EKEYWORDS="-* arm";
                 ECHOST="arm-unknown-linux-";
                 EUCLIBC_CPU="ARM920T";;
        x86) TARCH="x86";
             EKEYWORDS="-* x86";
             ECHOST="i386-unknown-linux-";
             EUCLIBC_CPU="GENERIC_386";;
esac
}
#-----------------------------------------------------------------------------
parse_baselayout() {
case $1 in
        help) cat << EOF

Supported baselayouts:
${GOOD}baselayout${NORMAL} Standard Gentoo baselayout.
${GOOD}baselayout-lite${NORMAL} Embedded Gentoo baselayout.
EOF
           exit 0;;
        baselayout) BPKG="sys-apps/baselayout";;
        baselayout-lite) BPKG="sys-apps/baselayout-lite";;
        *) eerror "Unsopported baselayout - '$1'!";
           parse_baselayout "help"; exit 1;;
esac
}
#-----------------------------------------------------------------------------
parse_libc () {
case $1 in
        help) cat << EOF

Supported C libraries:
${GOOD}gnu${NORMAL} GNU C Library (glibc). Pretty fat.
${GOOD}uclibc${NORMAL} uClibc. Intended for embedded systems.
${GOOD}diet${NORMAL} dietlibc. Minimal C library.
EOF
exit 0;;
        gnu) LPKG="sys-libs/glibc"; EELIBC="glibc";;
        uclibc) LPKG="sys-libs/uclibc"; EELIBC="uclibc";;
        diet) LPKG="dev-libs/dietlibc";;
        *) eerror "Unsopported C library - '$1'!";
           parse_libc "help";
           exit 1;;
esac
}
#-----------------------------------------------------------------------------
parse_utils () {
case $1 in
        help) cat << EOF

Supported init systems:
${GOOD}busybox${NORMAL} Busybox. Complete, but small toolset.
${GOOD}minutils${NORMAL} Set of minimalistic system utilities.
${GOOD}core${NORMAL} Standard GNU file utilities.
EOF
            exit 0;;
        busybox) UPKG="busybox";;
        minutils) UPKG="minutils";;
        core) UPKG="sys-apps/coreutils";;
        # embutils) NOT IN PORTAGE!
        *) eerror "Unsopported system toolset - '$1'!"; parse_utils "help"; 
exit 1;;
esac
}
#-----------------------------------------------------------------------------
doemerge() {
        [[ $# < 3 ]] && return 1
        name_without_slashes=`echo "$1" | tr "/" "_"`
        local 
logfile="${PORT_LOGDIR}/rootfsmaker-$2-${name_without_slashes}.log"
        export USE="$3 elibc_${EELIBC}"
        einfo "Log: ${logfile}"
        ebegin "Emerging $1"
        if [[ ${UOPTS/-v} != ${UOPTS} ]] ; then
                emerge info
                emerge $1 ${EOPTS} 2>&1 | tee ${logfile}
        else
                emerge $1 ${EOPTS} >& ${logfile}
        fi
        local _pipestatus=${PIPESTATUS[*]}
        [[ "${_pipestatus// /}" -eq 0 ]] || die "$1 failed :("
        eend 0
}
#-----------------------------------------------------------------------------
dounmerge() {
        name_without_slashes=`echo "$1" | tr "/" "_"`
        local 
logfile="${PORT_LOGDIR}/rootfsmaker-unmerge-${name_without_slashes}.log"
        export USE="elibc_${EELIBC}"
        einfo "Log: ${logfile}"
        ebegin "Unmerging $1"
        if [[ ${UOPTS/-v} != ${UOPTS} ]] ; then
                emerge info
                emerge -C $1 ${UOPTS} 2>&1 | tee ${logfile}
        else
                emerge -C $1 ${UOPTS} >& ${logfile}
        fi
        local _pipestatus=${PIPESTATUS[*]}
        [[ "${_pipestatus// /}" -eq 0 ]] || die "$1 failed :("
        eend 0
}
#-----------------------------------------------------------------------------
PORTDIR=$(portageq envvar PORTDIR)
PORT_LOGDIR=$(portageq envvar PORT_LOGDIR)
PORT_LOGDIR=${PORT_LOGDIR:-/var/log/portage}
export PORTAGE_TMPDIR="$(portageq envvar PORTAGE_TMPDIR)"
[[ ! -d ${PORT_LOGDIR} ]] && mkdir -p ${PORT_LOGDIR}
[[ ! -d ${PORTAGE_TMPDIR} ]] && mkdir -p ${PORTAGE_TMPDIR}

CBUILD=$(portageq envvar CBUILD)
CHOST=$(portageq envvar CHOST)

# Initial variable values
HARCH=$(env -uARCH portageq envvar ARCH)
TARCH=${HARCH}
EKEYWORDS="-* ${TARCH}"

#God will strike me down for this :/ (plz any1 knowing how to do it better, 
change it)
#this basically cuts the last part of arch name i.e. arch-arm-cutthis
arch_word_count=`echo ${CHOST} | tr "-" " " | wc -w`
arch_word_count=`expr ${arch_word_count} - 1`
ECHOST="`echo ${CHOST} | cut -d "-" -f -${arch_word_count}`-"

# Packages to emerge
LPKG="sys-libs/uclibc"
BPKG="sys-apps/baselayout-lite"
IPKG=""
UPKG="busybox"
XPKG=""

# Packages to unmerge
CPKG=""

# emerge parameters
UOPTS=
EOPTS=

# Options
STRIP="no"
FORCE_CREATE="no"
CROSS_COMPILING="yes"
EMERGE_SYSTEM_PACKAGES="yes"

# Other vars
EELIBC="uclibc"
EROOT="${PORTAGE_TMPDIR}/rootfsmaker"
UCLIBC_CPU=${HARCH}
export CBUILD=$(portageq envvar CBUILD)

#Logging activity
echo "`date` $0 $*" >> "${PORT_LOGDIR}/rootfsmaker.log"

# Parse arguments:
while getopts "l:b:u:a:sVhfvo:c:n" flag
do
        case $flag in
                l) parse_libc ${OPTARG};;
                b) parse_baselayout ${OPTARG};;
                u) parse_utils ${OPTARG};;
                a) parse_arch ${OPTARG};;
                s) STRIP="yes";;
                V) echo rootfsmaker version 0.2; exit 0;;
                h) usage; exit;;
                f) FORCE_CREATE="yes";;
                v) UOPTS="${UOPTS} -v";;
                o) EROOT=`echo ${OPTARG} | grep -q "^/" && echo ${OPTARG} || 
echo "${PWD}/${OPTARG}"`;;
                c) CPKG="${CPKG}${OPTARG} ";;
                n) EMERGE_SYSTEM_PACKAGES="no";;
                ?) usage; exit;;
        esac
done

# --nodeps is quite necessary, since all packages have unwanted system-related 
dependencies
EOPTS="${UOPTS} -u --nodeps"

# Extra packages to emerge:
shift `expr ${OPTIND} - 1`
XPKG=$*

#-----------------------------------------------------------------------------
if [[ -d ${EROOT} && ${FORCE_CREATE} != "yes" ]]; then
        eerror "Directory ${EROOT} already exists (try -f option). Exitting."
        exit 1
fi
mkdir -p ${EROOT}

# Export variables for emerge
export ARCH=${TARCH}
export ACCEPT_KEYWORDS=${EKEYWORDS}
if [[ ${CROSS_COMPILING} = "yes" ]]; then
        case ${EELIBC} in
                "uclibc") export CHOST="${ECHOST}uclibc";;
                "glibc") export CHOST="${ECHOST}gnu";;
                *) die "Unknown C library - '${EELIBC}'.";;
        esac
        export CROSS=${CHOST}-
        export CTARGET=${CHOST}
else
        # TODO
        export CBUILD=${CHOST}
        export CTARGET=${CHOST}
        export CHOST=${CHOST}
fi
export CFLAGS="-Os -pipe"
export CXXFLAGS=${CFLAGS}
export ROOT=${EROOT}
export FEATURES="-* -distcc ccache nodoc noinfo noman strict"
export CONFIG_PROTECT="-* ${ROOT}/etc"

# This should strip executables of unneeded content
export PORTAGE_STRIP_FLAGS="--strip-unneeded -R .comment"

# This should choose the C library we use
export ELIBC=${EELIBC}
export PORTAGE_LIBC=${ELIBC}
#export PROFILE_ARCH="arm920t"

# These are for uClibc:
export UCLIBC_CPU=${EUCLIBC_CPU}

# Print info
(
        einfo "Host Portage ARCH: ${HARCH}"
        einfo "Target Portage ARCH: ${TARCH}"
        echo
        einfo "rootfs location: ${EROOT}"
        einfo "Strip rootfs: ${STRIP}"
        echo
        if [[ ${EMERGE_SYSTEM_PACKAGES} = "yes" ]]; then
                einfo "C library: ${LPKG}"
                einfo "Baselayout: ${BPKG}"
                einfo "System toolset: ${UPKG}"
        else
                einfo "Skipping system packages"
        fi
        echo
        if [[ -n ${XPKG} ]] ; then
                einfo "Extra packages to install: ${XPKG}"
                echo
        fi
) >& ${PORT_LOGDIR}/rootfsmaker.log || exit 1
cat ${PORT_LOGDIR}/rootfsmaker.log
emerge info >> ${PORT_LOGDIR}/rootfsmaker.log

#Emerge system packages
if [[ ${EMERGE_SYSTEM_PACKAGES} = "yes" ]]; then
        # Emerge baselayout
        if [[ ${BPKG} == "sys-apps/baselayout-lite" ]] ; then
        mkdir -p /etc/portage
        grep -qs "baselayout-lite" /etc/portage/package.keywords \
                || echo "sys-apps/baselayout-lite -*" \
                >> /etc/portage/package.keywords
        fi
        doemerge ${BPKG} "baselayout" "-* bootstrap" \
                || die "Could not emerge ${BKPG}"
        
        # Emerge C library
        if [[ ${LPKG} = "sys-libs/glibc" ]] ; then
                doemerge ${LPKG} libc "userlocales -*" || die "Could emerge 
${LPKG}"
        else
                doemerge ${LPKG} libc "-*" || die "Could emerge ${LPKG}"
        fi
        
        # Emerge busybox
        doemerge ${UPKG} "utils" "-* static make-symlinks" \
                || die "Could not emerge busybox."
        #doemerge "tinylogin" "utils" "-* static make-symlinks" \
        #       || die "Could not emerge tinylogin."
fi

#Unmerge packages
if [[ -n ${CPKG} ]] ; then
        for SINGLE_PACKAGE_UNMERGE in ${CPKG};do
                dounmerge ${SINGLE_PACKAGE_UNMERGE} \
                        || die "Could not unmerge package 
'${SINGLE_PACKAGE_UNMERGE}'."
        done
fi

# Emerge extra packages
if [[ -n ${XPKG} ]] ; then
        for SINGLE_PACKAGE_MERGE in ${XPKG};do
                if [[ ${SINGLE_PACKAGE_MERGE} = "dropbear" ]] ; then
                        doemerge ${SINGLE_PACKAGE_MERGE} "extra" "-* minimal 
multicall static" \
                                || die "Could not emerge extra package 
'${SINGLE_PACKAGE_MERGE}'."
                else
                        doemerge ${SINGLE_PACKAGE_MERGE} "extra" "-* minimal 
multicall" \
                                || die "Could not emerge extra package 
'${SINGLE_PACKAGE_MERGE}'."
                fi
        done
fi

# Statistics
echo
einfo "rootfs size: `du -sh ${EROOT}`"

# Stripping the rootfs
if [[ ${STRIP} == "yes" ]] ; then
ebegin "Stripping rootfs"
(
        rm -R ${EROOT}/usr/include
        rm -R ${EROOT}/usr/share/doc
        rm -R ${EROOT}/usr/share/man
        rm -R ${EROOT}/tmp/*
        rm -R ${EROOT}/var/tmp/*
        rm -R ${EROOT}/var/db
        rm -R ${EROOT}/var/cache
        rm -R ${EROOT}/var/lib/portage
) >& ${PORTAGE_LOGDIR}/rootfsmaker.log \
|| die "Stripping error."
eend 0
einfo "rootfs size: `du -sh ${EROOT}`"
fi

# Finished
echo
einfo "Done. Enjoy your rootfs."
echo

Reply via email to