Subject: Re: Using build.sh and building from source.
To: Mark Thomas <thomas.s.mark@gmail.com>
From: Greg Troxel <gdt@ir.bbn.com>
List: netbsd-users
Date: 07/13/2005 08:40:08
Mark Thomas <thomas.s.mark@gmail.com> writes:

> I've been using NetBSD for a couple of years, I'm now comfortable
> enough with it to try my hand at building/upgrading the system from
> source. If anyone has time to answer these I'd appreciate it.
> 
> Assuming I've checkout the source for the 'release' branch. (
> http://netbsd.org/guide/en/chap-cvs.html#chap-cvs-fetch-source )
> 
> reference ( http://netbsd.org/guide/en/chap-build.html )

presumably '-r netbsd-2', so you can go from an installed 2.0 system
to the netbsd-2 branch

> 'build.sh' is an interface to all the make options? 

It's a wrapper around the entire build system, yes.

> It is best to always build and install 'tools' prior to, or during the
> "make release" and kernel building?

"./build.sh tools" will build tools, but if you "./build.sh release"
it will do tools and distribution first.

> Using "make release" and 'install=/' will upgrade the current system.
> i.e. postfix, ipf, etc. including /bin /sbin and others?

build.sh builds cross tools (to build the sources you are building on
the OS you are running, which can be different).  So use ./build.sh
release, not make release.  The latter will probably try native tools,
and if you're building current on 2.0 that won't work.  If you're
building netbsd-2 on 2.0 you'll probably get away with it, but it's
still wrong.

Make sure to install and boot a new kernel after building everything
but before installing userland.

> Do I have to "make release" to update just ipf? Or can I 'cd
> /src/usr.sbin/ipf && make install'?

If you have adequate tools, you can update single programs.  But
ipfilter is part kernel and part userland, and needs to be in sync.

You can also use the cross tools, by putting $TOOLS/bin in your path
and running 'nbmake-$arch' instead of make.  This installs into
DESTDIR by default, and you can eg
  nbmake-i386 DESTDIR=/ install
to install a single program.  I do this when changing a program, but
do full builds when updating.

> Do I have to build a new kernel prior to using the "make release" option?

Before installing the userland, yes, but you can build releases
without installing any of it, and ./build.sh release does that.

I append a script I use to run build.sh on the netbsd-2 branch.  It is
probably useful to read it as a complex example of using build.sh -
way more complex than you need.  Note that I force all the
obj/release/tool dirs; this enables me to build various branches on
the same machine without interference, and force build.sh to assume
some work is done when doing things in steps.

Note that this lives dangerously by installing userland and then
kernel, and then I reboot.  This is 99.9% likely to be ok on the
netbsd-2 branch, but a bad idea when upgrading to new branches.

This script is lame in that it requires being root.  Really one can
(and should) use the -U option for UNPRIVed builds. 


#!/bin/sh
# -*- shell-script -*-

## This script supports automatic building and installing of NetBSD
## along the 2 and 2.x branches (netbsd-2, netbsd-2-0, etc.).  It
## assumes that it is run as ./BUILD-2-0, and that src and xsrc are
## present in the current directory, checked out with matching tags.

if [ 0 != `id -u` ]; then
  echo "MUST BE ROOT TO RUN NETBSD BUILDALL"
  exit 1
fi

# This is possibly dangerous.  Remove uflag, or nuke /usr/obj if
# problematic.
uflag="-u"

SRCFILE=src/UPDATING
if [ ! -f $SRCFILE ]; then
    echo "$SRCFILE not present"
    exit 1
fi

# Use xsrc next to src, to enable cross builds.
X11SRCDIR=`/bin/pwd`/xsrc

# Build X if -x flag is given.
if [ "$1" = "-x" ]; then
    xflag="-x"
    shift
    X11SRCFILE=xsrc/xfree/xc/RELNOTES
    if [ ! -f $X11SRCDIR/$X11SRCFILE ]; then
	echo "$X11SRCFILE not present."
	exit 1
    fi
else
    xflag=""
fi

cmd=$1
if [ "$cmd" = "" ]; then
    cmd=distribution
fi
case "$cmd" in
    distribution|build)
    cmd=distribution
    target=distribution
    ;;
    release)
    target=release
    export BUILD_DONE=t
    echo "RELEASE: ASSUMING DISTRIBUTION ALREADY COMPLETE!"
    ;;
    iso)
    target=none
    echo "ISO: ASSUMING DISTRIBUTION AND RELEASE ALREADY COMPLETE!"
    ;;
    install)
    target="install=/"
    echo "INSTALL: ASSUMING DISTRIBUTION ALREADY COMPLETE!"
    ;;
    *)
    echo "Usage: ./BUILD-2-0 [-x] [distribution|release|iso|install]"
    ;;
esac

# determine arch (do a self-hosted build)
arch=`uname -m`

# find hostname and short version
hostname=`hostname`
host=`hostname | awk -F. '{print $1}'`

# look up kernel config in database
if [ -f hostname-kernel ]; then
  kern=`egrep $hostname hostname-kernel | awk '{print $2}'`
else
  # No databse - same as not found in database
  kern=""
fi

# if found, check for existence
if [ "$kern" != "" -a ! -f src/sys/arch/$arch/conf/$kern ]; then
  echo "CANNOT FIND KERNEL CONFIG src/sys/arch/$arch/conf/$kern!"
  exit 1
fi

# if not found, look for config named by hostname (but upper case)
hostuc=`echo $host | tr '[a-z]' '[A-Z]'`
if [ "$kern" = "" -a -f src/sys/arch/$arch/conf/$hostuc ]; then
    kern=$hostuc
fi

# Otherwise, use GENERIC.
if [ "$kern" = "" ]; then
    kern=GENERIC
fi

# Avoid conflict with builds of other branches.  Do not export, since
# if "BASE" that breaks src/sys/arch/i386/stand/biosboot.
BUILDBASE=/usr/obj/auto-2-0

# Set OBJDIR to be unique for this script and architecture.
export OBJDIR=$BUILDBASE/$arch

# Put tools near our obj tree.
export TOOLDIR=$BUILDBASE/tools; export TOOLDIR
TOOLSBIN=$TOOLDIR/bin

# Set up per-arch destdir.
export DESTDIR=$BUILDBASE/$arch/destdir

# Releasedir has $arch within it, so stay one level up.
export RELEASEDIR=$BUILDBASE/releasedir

case $target in
    distribution)
    # build tools
    echo -n "BUILDALL TOOLS start "; date
    (cd src && ./build.sh -O $OBJDIR -T $TOOLDIR $uflag tools || exit 1)
    echo -n "BUILDALL TOOLS finish "; date
    ;;

    *)
    echo "ASSUMING TOOLS ALREADY BUILT"
    ;;
esac

# Put tools in path
PATH=$TOOLSBIN:$PATH

# Run main target - distribution or release.
if [ "$target" != "none" ]; then
    echo -n "BUILDALL MAIN $target start "; date
    (cd src && ./build.sh -m $arch $xflag $uflag \
	-O $OBJDIR -T $TOOLDIR -D $DESTDIR -R $RELEASEDIR \
	-X $X11SRCDIR \
	$target || exit 1)
    echo -n "BUILDALL MAIN $target finish "; date
fi

# Do extra or sole processing for this command.
case $cmd in
    distribution)
    echo -n "BUILDALL KERNEL start $kern for $arch "; date
    (cd src && ./build.sh -m $arch $xflag $uflag \
	-O $OBJDIR -T $TOOLDIR -D $DESTDIR -R $RELEASEDIR \
	-X $X11SRCDIR \
	kernel=$kern || exit 1)
    echo -n "BUILDALL KERNEL finish $kern for $arch "; date
    ;;

    release)
    ;;

    iso)
    (cd src/etc && $TOOLDIR/bin/nbmake-$arch iso-image)
    ;;

    install)
    # install kernel
    (cd $OBJDIR/sys/arch/$arch/compile/$kern && make DESTDIR=/ install)
    # run etcmanage
    for step in 0 1 2 3 4 5 6 7 8 9; do
	echo BUILDALL: etcmanage: $step
	[ -f $DESTDIR/etc/defaults/rc.conf ] && \
	    etcmanage --update $DESTDIR
    done
    ;;

esac