Subject: Re: BUILDING howto (for beginners)
To: Julio Merino <>
From: Luke Mewburn <>
List: tech-userlevel
Date: 01/04/2003 23:27:23
On Fri, Jan 03, 2003 at 01:05:20PM +0100, Julio Merino wrote:
  | Hello,
  | [ To those who already read this mail in private: the patch has been
  |   changed a bit. ]
  | I've seen many people asking which is the right build method, order,
  | etc these days on the mailing lists. I think some information should
  | be provided about this in the BUILDING document (where it belongs).
  | Here is the patch I've done for BUILDING for review. It includes a
  | new section that aims to be a small howto for beginners. Yeah, I know
  | it can contain typos and maybe some kind of misinformation, but this
  | can be a good starting point ;). Comments?

Yes, a few.

(I haven't looked at the resultant file after applying the patch; I'm
attempting to parse the mandoc in my head ;-)

  | @@ -1113,10 +1125,233 @@
  |  To disable, use
  |  .El
  | +.
  | +.
  | +This section outlines the build procedure in a step by step form,
  | +specially addressed to beginners.
  | +It does not cover cross compilation.
  | +.Pp
  | +We will be using the
  | +.Nm nbmake
  | +command instead of the regular
  | +.Xr make 1 ;
  | +the reason is that the former is part of the toolchain used to build
  | +.Nx
  | +and does not rely on the current system installation.
  | +.Pp
  | +An alternative is to use the
  | +.Nm nbmake-${MACHINE}
  | +wrapper which calls the real
  | +.Nm nbmake
  | +binary.
  | +This wrapper remembers many of the variables you used in the last
  | +.Nm
  | +invocation, making further
  | +.Nm nbmake
  | +calls easier.
  | +We will avoid using it in the following examples so that the new
  | +user does not miss anything obvious.

Actually, I would prefer that you encourage the correct use of
nbmake-${MACHINE}; the fact that it remembers various settings is
extremely useful.

For example, I generally run to create nbmake-${MACHINE}
and nbmake, and then just invoke nbmake-${MACHINE} from then on...

  | +.Ss Building as root
  | +.
  | +Common steps:
  | +.Bl -enum
  | +.It
  | +Create basic directories using
  | +.Xr mkdir 1 .
  | +These include:
  | +.Bl -tag -width indent
  | +.It Va DESTDIR
  | +The directory that will contain the built
  | +.Nx
  | +system.
  | +It has no default, so you have to choose one.
  | +Use
  | +.Pa /usr/obj/root
  | +if you have no better idea (we will use this one in all of the
  | +examples).

It it not necessary to make DESTDIR; it will be created automatically.

You might want to mention that you're using ``/usr/obj'' as the
top-level of your build, and it is effectively a "scratch hierarchy".

On a related note, "/var/obj" would be a better example...

  | +The object tree, which defaults to
  | +.Pa /usr/obj .

I prefer MAKEOBJDIRPREFIX over BSDOBJDIR, as it doesn't need to
create the obj symlinks.

Unfortunately, MAKEOBJDIRPREFIX can't be set in /etc/mk.conf;
you need to set it in the environment, or call " -M /usr/obj"
and then use nbmake-$MACHINE.

  | +The directory that will contain the built
  | +.Nx
  | +release.
  | +It has no default, so you have to choose one.
  | +Use
  | +.Pa /usr/obj/release
  | +if you have no better idea (we will use this one in all of the
  | +examples).

RELEASEDIR is automatically created.

  | +.It Va TOOLDIR
  | +The directory that contains the toolchain.
  | +Defaults to
  | +.Pa /usr/tools .

TOOLDIR is automatically created.

Note, whilst I used to share one TOOLDIR between multiple different
builds, I ran into some issues between 1.6 and -current, so I've since
decided to burn a bit more CPU time and disk space, and maintain per
"build" tooldirs.  So, in this case, ``/usr/obj/tools''

  | +Given the above suggestions, you can do:
  | +.Bd -literal -offset indent
  | +# mkdir -p /usr/obj

This is the only necessary one

  | +# mkdir -p /usr/obj/root
  | +# mkdir -p /usr/obj/release
  | +# mkdir -p /usr/tools

These are unnecessary.

  | +Please read the
  | +section for more information on these (and other) variables.
  | +.Pp
  | +It is a good idea to set these variables in the
  | +.Pa /etc/mk.conf
  | +file, so you do not have to pass them over and over again to the
  | +.Nm
  | +script (anyway, we will use these values in all of the calls to
  | +illustrate how it is done).

Since I'm often building to multiple platforms or from multiple source
trees, each with a separate equivalent to "/usr/obj" (I use
"/var/scratch/obj.${MACHINE}"), I can't really rely upon mk.conf.
I just prefer to invoke with a wrapper which sets my appropriate
arguments, including the per-build "scratch root". 

  | +.It
  | +Build the toolchain.
  | +Before you can build anything else from the source tree, you need
  | +a set of tools under
  | +.Va TOOLDIR .
  | +These can be built using:
  | +.Bd -literal -offset indent
  | +# ./ -t -T /usr/tools -O /usr/obj
  | +.Ed

  | +.Pp
  | +The tools do not need to be recreated before each build (except as
  | +noted by the
  | +file), so you can safely keep them between builds.

Generally, UPDATING is for people who don't use and/or who
build to DESTDIR=/.  It shouldn't be necessary to track UPDATING if
you're using to build to DESTDIR != /. 

  | +.It
  | +Build, install and
  | +.Em boot
  | +a new kernel.
  | +See
  | +.Xr config 8
  | +for more information on how to do this.

I would suggest using " [other options] -k SOMEKERNEL" here,
because it greatly simplifies configuring and building a kernel,
especially if you're cross compiling from another platform or from an
older release.

  | +.It
  | +Cleanup work directories.
  | +It is recommended that you clean
  | +.Va DESTDIR
  | +and
  | +.Va OBJDIR
  | +before starting the build to avoid problems.

This is not necessary if you're not using -u (UPDATE),
as directories will be cleaned for you.

  | +.El
  | +.Pp
  | +When all the above steps are done, you are ready to build the system.
  | +Sources can produce different results:
  | +.Bl -enum
  | +.It
  | +A release.
  | +It provides all the compressed system sets, plus installation floppies
  | +and kernels.
  | +See
  | +.Xr release 7
  | +for more information.
  | +.Pp
  | +To build a release, use the following command:
  | +.Bd -literal -offset indent
  | +# ./ -D /usr/obj/root -R /usr/obj/release
  | +  -T /usr/tools -O /usr/obj
  | +.Ed
  | +.Pp
  | +This is the most time consuming process.
  | +When it has finished, you have a full release under
  | +You can upgrade your system by using the boot floppies under that
  | +directory or unpack the system sets over the running system.
  | +.It
  | +Compressed system sets.
  | +This provides all the system sets, but nothing else.
  | +Useful if you want to update your system, but do not want all the
  | +extra stuff of a release (thus shortening the build time a lot).
  | +.Pp
  | +Start by building a distribution under
  | +.Va DESTDIR :
  | +.Bd -literal -offset indent
  | +# ./ -d -D /usr/obj/root -T /usr/tools -O /usr/obj
  | +.Ed
  | +.Pp
  | +Generate the sets:
  | +.Bd -literal -offset indent
  | +# cd distrib/sets
  | +# mkdir -p /usr/obj/release/binary/sets
  | +# /usr/tools/bin/nbmake sets DESTDIR=/usr/obj/root
  | +  RELEASEDIR=/usr/obj/release
  | +.Ed
  | +.Pp
  | +And install them:
  | +.Bd -literal -offset indent
  | +# cd distrib/sets
  | +# /usr/tools/bin/nbmake installsets DESTDIR=/usr/obj/root
  | +  RELEASEDIR=/usr/obj/release INSTALLDIR=/
  | +.Ed
  | +.It
  | +A distribution.
  | +This will build the system, but will not generate any kind of release
  | +file (that is, nothing will be written to the
  | +tree).
  | +Useful to easily update a single machine.
  | +.Pp
  | +This is done without the
  | +.Nm
  | +script, so you need to call the
  | +.Xr make 1
  | +program directly. To build the distribution (from source's top
  | +directory):
  | +.Bd -literal -offset indent
  | +# /usr/tools/bin/nbmake buildworld BSDOBJDIR=/usr/obj
  | +  TOOLDIR=/usr/tools DESTDIR=/usr/obj/root
  | +.Ed
  | +.Pp
  | +To install the results:
  | +.Bd -literal -offset indent
  | +# /usr/tools/bin/nbmake installworld BSDOBJDIR=/usr/obj
  | +  TOOLDIR=/usr/tools DESTDIR=/usr/obj/root INSTALLWORLDDIR=/
  | +.Ed
  | +.El
  | +.Pp
  | +Remember to run
  | +.Xr etcupdate 8
  | +after upgrading your system to bring
  | +.Pa /etc
  | +up to date.
  | +.
  | +.Ss Building as a regular user
  | +.
  | +The entire build process can be done as an unprivileged user.
  | +This is in fact recommended, so you avoid screwing up your running
  | +system.
  | +.Pp
  | +Make sure the directories
  | +.Pa DESTDIR ,
  | +.Pa OBJDIR ,
  | +and
  | +.Pa TOOLDIR
  | +have the right permissions for your user (read and write).
  | +It does not need write access to the source tree.
  | +.Pp
  | +Everything else is the same, with some small exceptions: when calling
  | +the
  | +.Nm
  | +script, you have to pass it the
  | +.Fl U
  | +option (that stands for unprived), and when directly calling
  | +.Nm nbmake
  | +you need to pass the extra argument
  | +.Ql UNPRIVED=yes .
  | +This will generate meta information required to set the right
  | +permissions on the generated files.
  | +.
  |  .Sh SEE ALSO
  | +.
  |  .Xr make 1 ,
  | +.Xr mk.conf 5 ,
  |  .Xr hier 7 ,
  | -.Xr release 7
  | +.Xr release 7 ,
  | +.Xr config 8 ,
  | +.Xr etcupdate 8
  |  .
  |  .Sh HISTORY

You might want to mention "make installworld"  ( -i).