development(7)
NAME
- development - introduction to development with the FreeBSD
- codebase
DESCRIPTION
- This manual page describes how an ordinary sysop, UNIX ad
- min, or developer can, without any special permission, obtain, maintain,
- and modify
the FreeBSD codebase as well as how to maintain a master
- build which can
then be exported to other machines in your network. This
- manual page is
targeted to system operators, programmers, and developers.
- Please note that what is being described here is based on a
- complete
FreeBSD environment, not just the FreeBSD kernel. The meth
- ods described
here are as applicable to production installations as it is
- to development environments. You need a good 12-17GB of disk space on
- one machine
to make this work conveniently.
SETTING UP THE ENVIRONMENT ON THE MASTER SERVER
- Your master server should always run a stable, production
- version of the
FreeBSD operating system. This does not prevent you from
- doing -CURRENT
builds or development. The last thing you want to do is to
- run an unstable environment on your master server which could lead to a
- situation
where you lose the environment and/or cannot recover from a
- mistake.
- Create a huge partition called /FreeBSD. 8-12GB is recom
- mended. This
partition will contain nearly all the development environ
- ment, including
the CVS tree, broken-out source, and possibly even object
- files. You are
going to export this partition to your other machines via a
- READ-ONLY NFS
export so do not mix it with other more security-sensitive
- partitions.
- You have to make a choice in regards to /usr/obj. You can
- put /usr/obj
in /FreeBSD or you can make /usr/obj its own partition. I
- recommend making it a separate partition for several reasons. First, as
- a safety measure since this partition is written to a great deal. Sec
- ond, because
you typically do not have to back it up. Third, because it
- makes it far
easier to mix and match the development environments which
- are described
later in this document. I recommend a /usr/obj partition of
- at least
5GB.
- On the master server, use cvsup(1) (ports/net/cvsup) to au
- tomatically
pull down and maintain the FreeBSD CVS archive once a day.
- The first
pull will take a long time, it is several gigabytes, but
- once you have
it, the daily syncs will be quite small.
mkdir /FreeBSD/FreeBSD-CVS
rm -rf /home/ncvs
ln -s /FreeBSD/FreeBSD-CVS /home/ncvs
- The cron(8) job should look something like this (please ran
- domize the
time of day!). Note that you can use the cvsup(1) configu
- ration file
example directly from /usr/share/examples without modifica
- tion by supplying appropriate arguments to cvsup(1).
33 6 * * * /usr/local/bin/cvsup -g -r 20 -L 2 -h
- cvsup.freebsd.org /usr/share/examples/cvsup/cvs-supfile
- Run the cvsup(1) manually the first time to pull down the
- archive. It
could take all day depending on how fast your connection is!
- You will
run all cvsup(1) and cvs(1) operations as ``root'' and you
- need to set up
a ~/.cvsrc (/root/.cvsrc) file, as shown below, for proper
- cvs(1) operation. Using ~/.cvsrc to specify cvs(1) defaults is an ex
- cellent way to
``file and forget'', but you should never forget that you
- put them in
there.
# cvs -q
diff -u
update -Pd
checkout -P
- Now use cvs(1) to check out a -STABLE source tree and a
- -CURRENT source
tree, as well as ports and docs, to create your initial
- source environment. Keeping the broken-out source and ports in /FreeBSD
- allows you to
export it to other machines via read-only NFS. This also
- means you only
need to edit/maintain files in one place and all your
- clients automatically pick up the changes.
mkdir /FreeBSD/FreeBSD-4.x
mkdir /FreeBSD/FreeBSD-current
- cd /FreeBSD/FreeBSD-4.x
cvs -d /home/ncvs checkout -rRELENG_4 src
- cd /FreeBSD/FreeBSD-current
cvs -d /home/ncvs checkout src
cvs -d /home/ncvs checkout ports
cvs -d /home/ncvs checkout doc
- Now create a softlink for /usr/src and /usr/src2. On the
- main server I
always point /usr/src at -STABLE and /usr/src2 at -CURRENT.
- On client
machines I usually do not have a /usr/src2 and I make
- /usr/src point at
whatever version of FreeBSD the client box is intended to
- run.
cd /usr
rm -rf src src2
ln -s /FreeBSD/FreeBSD-4.x/src src (could be -CUR
- RENT on a client)
ln -s /FreeBSD/FreeBSD-current/src src2 (MASTER SERVER
- ONLY)
- Now you have to make a choice for /usr/obj. Well, hopefully
- you made it
already and chose the partition method. If you chose poorly
- you probably
intend to put it in /FreeBSD and, if so, this is what you
- want to do:
(ONLY IF YOU MADE A POOR CHOICE AND PUT /usr/obj in
- /FreeBSD!)
mkdir /FreeBSD/obj
cd /usr
rm -rf obj
ln -s /FreeBSD/obj obj
- Alternatively you may chose simply to leave /usr/obj in
- /usr. If your
/usr is large enough this will work, but I do not recommend
- it for safety
reasons (/usr/obj is constantly being modified, /usr is
- not).
- Note that exporting /usr/obj via read-only NFS to your other
- boxes will
allow you to build on your main server and install from your
- other boxes.
If you also want to do builds on some or all of the clients
- you can simply have /usr/obj be a local directory on those clients.
- You should
never export /usr/obj read-write, it will lead to all sorts
- of problems
and issues down the line and presents a security problem as
- well. It is
far easier to do builds on the master server and then only
- do installs on
the clients.
- I usually maintain my ports tree via CVS. It is sitting
- right there in
the master CVS archive and I have even told you to check it
- out (see
above). With some fancy softlinks you can make the ports
- tree available
both on your master server and on all of your other ma
- chines. Note that
the ports tree exists only on the HEAD CVS branch, so its
- always -CURRENT
even on a -STABLE box. This is what you do:
(THESE COMMANDS ON THE MASTER SERVER AND ON ALL CLIENTS)
cd /usr
rm -rf ports
ln -s /FreeBSD/FreeBSD-current/ports ports
- cd /usr/ports (this pushes in
- to the softlink)
rm -rf distfiles (ON MASTER SERV
- ER ONLY)
ln -s /usr/ports.distfiles distfiles (ON MASTER SERV
- ER ONLY)
- mkdir /usr/ports.distfiles
mkdir /usr/ports.workdir
- Since /usr/ports is softlinked into what will be read-only
- on all of your
clients, you have to tell the ports system to use a differ
- ent working
directory to hold ports builds. You want to add a line to
- your
make.conf(5) file on the master server and on all your
- clients:
WRKDIRPREFIX=/usr/ports.workdir
- You should try to make the directory you use for the ports
- working directory as well as the directory used to hold distfiles consis
- tent across
all of your machines. If there is not enough room in
/usr/ports.distfiles and /usr/ports.workdir I usually make
- those softlinks (since this is on /usr these are per-machine) to where
- the distfiles and working space really are.
EXPORTING VIA NFS FROM THE MASTER SERVER
- The master server needs to export /FreeBSD and /usr/obj via
- NFS so all
the rest of your machines can get at them. I strongly rec
- ommend using a
read-only export for both security and safety. The environ
- ment I am
describing in this manual page is designed primarily around
- read-only NFS
exports. Your exports file on the master server should con
- tain the following lines:
/FreeBSD -ro -alldirs -maproot=root: -network YOURLAN
- -mask YOURLANMASK
/usr/obj -ro -alldirs -maproot=root: -network YOURLAN
- -mask YOURLANMASK
- Of course, NFS server operations must also be configured on
- that machine.
This is typically done via your /etc/rc.conf:
nfs_server_enable="YES"
nfs_server_flags="-u -t -n 4"
THE CLIENT ENVIRONMENT
- All of your client machines can import the development/build
- environment
directory simply by NFS mounting /FreeBSD and /usr/obj from
- the master
server. A typical /etc/fstab entry on your client machines
- will be something like this:
masterserver:/FreeBSD /FreeBSD nfs ro,bg
- 0 0
masterserver:/usr/obj /usr/obj nfs ro,bg
- 0 0
- And, of course, you should configure the client for NFS
- client operations
via /etc/rc.conf. In particular, this will turn on nf
- siod(8) which will
improve client-side NFS performance:
nfs_client_enable="YES"
- Each client should create softlinks for /usr/ports and
- /usr/src that
point into the NFS-mounted environment. If a particular
- client is running -CURRENT, /usr/src should be a softlink to
/FreeBSD/FreeBSD-current/src. If it is running -STABLE,
- /usr/src should
be a softlink to /FreeBSD/FreeBSD-4.x/src. I do not usually
- create a
/usr/src2 softlink on clients, that is used as a convenient
- shortcut when
working on the source code on the master server only and
- could create
massive confusion (of the human variety) on a client.
(ON EACH CLIENT)
cd /usr
rm -rf ports src
ln -s /FreeBSD/FreeBSD-current/ports ports
ln -s /FreeBSD/FreeBSD-XXX/src src
- Do not forget to create the working directories so you can
- build ports,
as previously described. If these are not good locations,
- make them
softlinks to the correct location. Remember that
- /usr/ports/distfiles is
exported by the master server and is therefore going to
- point to the same
place (typically /usr/ports.distfiles) on every machine.
mkdir /usr/ports.distfiles
mkdir /usr/ports.workdir
BUILDING KERNELS
- Here is how you build a -STABLE kernel (on your main devel
- opment box).
If you want to create a custom kernel, copy GENERIC to
- KERNELNAME and
then edit it before configuring and building. The kernel
- configuration
file lives in /usr/src/sys/i386/conf/KERNELNAME.
cd /usr/src
make buildkernel KERNCONF=KERNELNAME
- WARNING! If you are familiar with the old config/cd/make
- method of building a -STABLE kernel, note that the config(8) method will
- put the build
environment in /usr/src/sys/i386/compile/KERNELNAME instead
- of in
/usr/obj.
- Building a -CURRENT kernel
cd /usr/src2 (on the master server)
make buildkernel KERNCONF=KERNELNAME
INSTALLING KERNELS
- Installing a -STABLE kernel (typically done on a client, on
- ly do this on
your main development server if you want to install a new
- kernel for your
main development server):
cd /usr/src
make installkernel KERNCONF=KERNELNAME
- If you are using the older config/cd/make build mechanism
- for -STABLE,
you would install using:
cd /usr/src/sys/i386/compile/KERNELNAME
make install
- Installing a -CURRENT kernel (typically done only on a
- client)
(remember /usr/src is pointing to the client's specific
- environment)
cd /usr/src
make installkernel KERNCONF=KERNELNAME
BUILDING THE WORLD
- This environment is designed such that you do all builds on
- the master
server, and then install from each client. You can do
- builds on a client
only if /usr/obj is local to that client. Building the
- world is easy:
cd /usr/src
make buildworld
- If you are on the master server you are running in a -STABLE
- environment,
but that does not prevent you from building the -CURRENT
- world. Just
cd(1) into the appropriate source directory and you are set.
- Do not
accidentally install it on your master server though!
cd /usr/src2
make buildworld
INSTALLING THE WORLD
- You can build on your main development server and install on
- clients.
The main development server must export /FreeBSD and
- /usr/obj via readonly NFS to the clients.
- NOTE!!! If /usr/obj is a softlink on the master server, it
- must also be
the EXACT SAME softlink on each client. If /usr/obj is a
- directory in
/usr or a mount point on the master server, then it must be
- (interchangeably) a directory in /usr or a mount point on each client.
- This is
because the absolute paths are expected to be the same when
- building the
world as when installing it, and you generally build it on
- your main
development box and install it from a client. If you do not
- set up
/usr/obj properly you will not be able to build on machine
- and install on
another.
(ON THE CLIENT)
(remember /usr/src is pointing to the client's specific
- environment)
cd /usr/src
make installworld
- WARNING! If builds work on the master server but installs do
- not work
from the clients, for example you try to install and the
- client complains
that the install tried to write into the read-only /usr/obj,
- then it is
likely that the make.conf(5) file on the client does not
- match the one on
the master server closely enough and the install is trying
- to install
something that was not built.
DOING DEVELOPMENT ON A CLIENT (NOT JUST INSTALLING)
- Developers often want to run buildkernel's or buildworld's
- on client
boxes simply to life-test the box. You do this in the same
- manner that
you buildkernel and buildworld on your master server. All
- you have to do
is make sure that /usr/obj is pointing to local storage. If
- you followed
my advise and made /usr/obj its own partition on the master
- server, then
it is typically going to be an NFS mount on the client.
- Simply unmounting /usr/obj will leave you with a /usr/obj that is a subdi
- rectory in
/usr which is typically local to the client. You can then
- do builds to
your heart's content!
MAINTAINING A LOCAL BRANCH
- I have described how to maintain two versions of the source
- tree, a stable version in /FreeBSD/FreeBSD-4.x and a current version in
/FreeBSD/FreeBSD-current. There is absolutely nothing pre
- venting you
from breaking out other versions of the source tree into
- /FreeBSD/XXX.
In fact, my /FreeBSD partition also contains OpenBSD, NetB
- SD, and various
flavors of Linux. You may not necessarily be able to build
- non-FreeBSD
operating systems on your master server, but being able to
- collect and
manage source distributions from a central server is a very
- useful thing
to be able to do and you can certainly export to machines
- which can build
those other operating systems.
- Many developers choose to maintain a local branch of FreeBSD
- to test
patches or build a custom distribution. This can be done
- with CVS or
another source code management system (SubVersion, Perforce,
- BitKeeper)
with its own repository. Since the main FreeBSD tree is
- based on CVS,
the former is convenient.
- First, you need to modify your cvsup(1) environment to avoid
- it modifying
the local changes you have committed to the repository. It
- is important
to remove the delete keyword from your supfile and to add
- the CVSROOT
subdirectory to your refuse file. For more information, see
- cvsup(1).
- The FreeBSD version of cvs(1) examines a custom environmen
- tal variable,
CVS_LOCAL_BRANCH_NUM, which specifies an integer to use when
- doing a
cvs(1) tag/rtag. Set this number to something high (say
- 1000) to avoid
colliding with potential future branches of the main reposi
- tory. For
example, branching a file with version 1.4 produces
- 1.4.1000. Future
commits to this branch will produce revisions 1.4.1000.1,
- 1.4.1000.2,
etc.
- To fork your local branch, do:
cvs rtag -r RELENG_4 -b LOCAL_RELENG_4 src
- After this, you can check out a copy from your local reposi
- tory using the
new tag and begin making changes and committing them. For
- more information on using CVS, see cvs(1).
- WARNING! The cvsup(1) utility may blow away changes made on
- a local
branch in some situations. This has been reported to occur
- when the master CVS repository is directly manipulated or an RCS file is
- changed. At
this point, cvsup(1) notices that the client and server have
- entirely
different RCS files, so it does a full replace instead of
- trying to send
just deltas. Ideally this situation should never arise, but
- in the real
world it happens all the time.
- While this is the only scenario where the problem should
- crop up, there
have been some suspicious-sounding reports of CVS_LO
- CAL_BRANCH_NUM lossage that cannot be explained by this alone. Bottom line
- is, if you
value your local branch then you should back it up before
- every update.
UPDATING VIA CVS
- The advantage of using cvsup(1) to maintain an updated copy
- of the CVS
repository instead of using it to maintain source trees di
- rectly is that
you can then pick and choose when you bring your source tree
- (or pieces
of your source tree) up to date. By using a cron(8) job to
- maintain an
updated CVS repository, you can update your source tree at
- any time without any network cost as follows:
(on the main development server)
cd /usr/src
cvs -d /home/ncvs update
cd /usr/src2
cvs -d /home/ncvs update
cd /usr/ports
cvs -d /home/ncvs update
- It is that simple, and since you are exporting the whole lot
- to your
clients, your clients have immediate visibility into the up
- dated source.
This is a good time to also remind you that most of the
- cvs(1) operations
you do will be done as ``root'', and that certain options
- are required
for CVS to operate properly on the FreeBSD repository. For
- example, -Pd
is necessary when running cvs update. These options are
- typically placed
in your ~/.cvsrc (as already described) so you do not have
- to respecify
them every time you run a cvs(1) command. Maintaining the
- CVS repository
also gives you far more flexibility in regards to breaking
- out multiple
versions of the source tree. It is a good idea to give your
- /FreeBSD
partition a lot of space (I recommend 8-12GB) precisely for
- that reason.
If you can make it 15GB I would do it.
- I generally do not cvs update via a cron(8) job. This is
- because I generally want the source to not change out from under me when
- I am developing code. Instead I manually update the source every so of
- ten... when I
feel it is a good time. My recommendation is to only keep
- the CVS repository synchronized via cron(8).
SEE ALSO
- crontab(1), crontab(5), make.conf(5), build(7), firewall(7),
- release(7),
tuning(7), diskless(8)
HISTORY
- The development manual page was originally written by
- Matthew Dillon
<dillon@FreeBSD.org> and first appeared in FreeBSD 5.0, De
- cember 2002.
- BSD December 21, 2002