xref: /freebsd/share/man/man7/development.7 (revision 6e0da4f753ed6b5d26395001a6194b4fdea70177)
1.\" Copyright (C) 1998 Matthew Dillon. All rights reserved.
2.\"
3.\" Redistribution and use in source and binary forms, with or without
4.\" modification, are permitted provided that the following conditions
5.\" are met:
6.\" 1. Redistributions of source code must retain the above copyright
7.\"    notice, this list of conditions and the following disclaimer.
8.\" 2. Redistributions in binary form must reproduce the above copyright
9.\"    notice, this list of conditions and the following disclaimer in the
10.\"    documentation and/or other materials provided with the distribution.
11.\"
12.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15.\" ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22.\" SUCH DAMAGE.
23.\"
24.\" $FreeBSD$
25.\"
26.Dd December 21, 2002
27.Dt DEVELOPMENT 7
28.Os
29.Sh NAME
30.Nm development
31.Nd "introduction to development with the FreeBSD codebase"
32.Sh DESCRIPTION
33This manual page describes how an ordinary sysop,
34.Ux
35admin, or developer
36can, without any special permission, obtain, maintain, and modify the
37.Fx
38codebase as well as how to maintain a master build which can
39then be exported to other machines in your network.
40This manual page
41is targeted to system operators, programmers, and developers.
42.Pp
43Please note that what is being described here is based on a complete
44.Fx
45environment, not just the
46.Fx
47kernel.
48The methods described
49here are as applicable to production installations as it is to development
50environments.
51You need a good 12-17GB of disk space on one machine to make this work
52conveniently.
53.Sh SETTING UP THE ENVIRONMENT ON THE MASTER SERVER
54Your master server should always run a stable, production version of the
55.Fx
56operating system.
57This does not prevent you from doing -CURRENT
58builds or development.
59The last thing you want to do is to run an
60unstable environment on your master server which could lead to a situation
61where you lose the environment and/or cannot recover from a mistake.
62.Pp
63Create a huge partition called
64.Pa /FreeBSD .
658-12GB is recommended.
66This partition will contain nearly all the development environment,
67including the CVS tree, broken-out source, and possibly even object files.
68You are going to export this partition to your other machines via a
69READ-ONLY NFS export so do not mix it with other more security-sensitive
70partitions.
71.Pp
72You have to make a choice in regards to
73.Pa /usr/obj .
74You can put
75.Pa /usr/obj
76in
77.Pa /FreeBSD
78or you can make
79.Pa /usr/obj
80its own partition.
81I recommend making it a separate partition for several reasons.
82First,
83as a safety measure since this partition is written to a great deal.
84Second, because you typically do not have to back it up.
85Third, because it makes it far easier to mix and match the development
86environments which are described later in this document.
87I recommend a
88.Pa /usr/obj
89partition of at least 5GB.
90.Pp
91On the master server, use
92.Xr cvsup 1
93to automatically pull down and maintain
94the
95.Fx
96CVS archive once a day.
97The first pull will take a long time,
98it is several gigabytes, but once you have it, the daily syncs will be quite
99small.
100.Bd -literal -offset 4n
101mkdir /FreeBSD/FreeBSD-CVS
102rm -rf /home/ncvs
103ln -s /FreeBSD/FreeBSD-CVS /home/ncvs
104.Ed
105.Pp
106The
107.Xr cron 8
108job should look something like this (please randomize the time of
109day!).
110Note that you can use the
111.Xr cvsup 1
112configuration file example directly from
113.Pa /usr/share/examples
114without modification by supplying appropriate arguments
115to
116.Xr cvsup 1 .
117.Bd -literal -offset 4n
11833 6 * * *      /usr/local/bin/cvsup -g -r 20 -L 2 -h cvsup.freebsd.org /usr/share/examples/cvsup/cvs-supfile
119.Ed
120.Pp
121Run the
122.Xr cvsup 1
123manually the first time to pull down the archive.
124It could take
125all day depending on how fast your connection is!
126You will run all
127.Xr cvsup 1
128and
129.Xr cvs 1
130operations as
131.Dq Li root
132and you need to set up a
133.Pa ~/.cvsrc
134.Pq Pa /root/.cvsrc
135file, as shown below, for proper
136.Xr cvs 1
137operation.
138Using
139.Pa ~/.cvsrc
140to specify
141.Xr cvs 1
142defaults is an excellent way to
143.Dq "file and forget" ,
144but you should never forget that you put them in there.
145.Bd -literal -offset 4n
146# cvs -q
147diff -u
148update -Pd
149checkout -P
150.Ed
151.Pp
152Now use
153.Xr cvs 1
154to check out a -STABLE source tree and a -CURRENT source tree,
155as well as ports and docs, to create your initial source environment.
156Keeping the broken-out source and ports in
157.Pa /FreeBSD
158allows you to export
159it to other machines via read-only NFS.
160This also means you only need to edit/maintain files in one place and all
161your clients automatically pick up the changes.
162.Bd -literal -offset 4n
163mkdir /FreeBSD/FreeBSD-4.x
164mkdir /FreeBSD/FreeBSD-current
165
166cd /FreeBSD/FreeBSD-4.x
167cvs -d /home/ncvs checkout -rRELENG_4 src
168
169cd /FreeBSD/FreeBSD-current
170cvs -d /home/ncvs checkout src
171cvs -d /home/ncvs checkout ports
172cvs -d /home/ncvs checkout doc
173.Ed
174.Pp
175Now create a softlink for
176.Pa /usr/src
177and
178.Pa /usr/src2 .
179On the main server I always point
180.Pa /usr/src
181at -STABLE and
182.Pa /usr/src2
183at -CURRENT.
184On client machines I usually do not have a
185.Pa /usr/src2
186and I make
187.Pa /usr/src
188point at whatever version of
189.Fx
190the client box is intended to
191run.
192.Bd -literal -offset 4n
193cd /usr
194rm -rf src src2
195ln -s /FreeBSD/FreeBSD-4.x/src src	(could be -CURRENT on a client)
196ln -s /FreeBSD/FreeBSD-current/src src2	(MASTER SERVER ONLY)
197.Ed
198.Pp
199Now you have to make a choice for
200.Pa /usr/obj .
201Well, hopefully you made it already and chose the partition method.
202If you
203chose poorly you probably intend to put it in
204.Pa /FreeBSD
205and, if so, this is
206what you want to do:
207.Bd -literal -offset 4n
208(ONLY IF YOU MADE A POOR CHOICE AND PUT /usr/obj in /FreeBSD!)
209mkdir /FreeBSD/obj
210cd /usr
211rm -rf obj
212ln -s /FreeBSD/obj obj
213.Ed
214.Pp
215Alternatively you may chose simply to leave
216.Pa /usr/obj
217in
218.Pa /usr .
219If your
220.Pa /usr
221is large enough this will work, but I do not recommend it for
222safety reasons
223.Pa ( /usr/obj
224is constantly being modified,
225.Pa /usr
226is not).
227.Pp
228Note that exporting
229.Pa /usr/obj
230via read-only NFS to your other boxes will
231allow you to build on your main server and install from your other boxes.
232If you also want to do builds on some or all of the clients you can simply
233have
234.Pa /usr/obj
235be a local directory on those clients.
236You should never export
237.Pa /usr/obj
238read-write, it will lead to all sorts of
239problems and issues down the line and presents a security problem as well.
240It is far easier to do builds on the master server and then only do installs
241on the clients.
242.Pp
243I usually maintain my ports tree via CVS.
244It is sitting right there in the master CVS archive and I have even told you
245to check it out (see above).
246With some fancy softlinks you can make the ports tree available both on your
247master server and on all of your other machines.
248Note that the ports tree exists only on the HEAD CVS branch, so its always
249-CURRENT even on a -STABLE box.
250This is what you do:
251.Bd -literal -offset 4n
252(THESE COMMANDS ON THE MASTER SERVER AND ON ALL CLIENTS)
253cd /usr
254rm -rf ports
255ln -s /FreeBSD/FreeBSD-current/ports ports
256
257cd /usr/ports   			(this pushes into the softlink)
258rm -rf distfiles			(ON MASTER SERVER ONLY)
259ln -s /usr/ports.distfiles distfiles	(ON MASTER SERVER ONLY)
260
261mkdir /usr/ports.distfiles
262mkdir /usr/ports.workdir
263.Ed
264.Pp
265Since
266.Pa /usr/ports
267is softlinked into what will be read-only on all of your
268clients, you have to tell the ports system to use a different working
269directory to hold ports builds.
270You want to add a line to your
271.Pa /etc/make.conf
272file on the master server
273and on all your clients:
274.Bd -literal -offset 4n
275WRKDIRPREFIX=/usr/ports.workdir
276.Ed
277.Pp
278You should try to make the directory you use for the ports working directory
279as well as the directory used to hold distfiles consistent across all of your
280machines.
281If there is not enough room in
282.Pa /usr/ports.distfiles
283and
284.Pa /usr/ports.workdir
285I usually make those softlinks (since this is on
286.Pa /usr
287these are per-machine) to
288where the distfiles and working space really are.
289.Sh EXPORTING VIA NFS FROM THE MASTER SERVER
290The master server needs to export
291.Pa /FreeBSD
292and
293.Pa /usr/obj
294via NFS so all the
295rest of your machines can get at them.
296I strongly recommend using a read-only export for both security and safety.
297The environment I am describing in this manual page is designed primarily
298around read-only NFS exports.
299Your exports file on the master server should contain the following lines:
300.Bd -literal -offset 4n
301/FreeBSD -ro -alldirs -maproot=root: -network YOURLAN -mask YOURLANMASK
302/usr/obj -ro -alldirs -maproot=root: -network YOURLAN -mask YOURLANMASK
303.Ed
304.Pp
305Of course, NFS server operations must also be configured on that machine.
306This is typically done via your
307.Pa /etc/rc.conf :
308.Bd -literal -offset 4n
309nfs_server_enable="YES"
310nfs_server_flags="-u -t -n 4"
311.Ed
312.Sh THE CLIENT ENVIRONMENT
313All of your client machines can import the development/build environment
314directory simply by NFS mounting
315.Pa /FreeBSD
316and
317.Pa /usr/obj
318from the master server.
319A typical
320.Pa /etc/fstab
321entry on your client machines will be something like this:
322.Bd -literal -offset 4n
323masterserver:/FreeBSD     /FreeBSD        nfs     ro,bg    0       0
324masterserver:/usr/obj     /usr/obj        nfs     ro,bg    0       0
325.Ed
326.Pp
327And, of course, you should configure the client for NFS client operations
328via
329.Pa /etc/rc.conf .
330In particular, this will turn on
331.Xr nfsiod 8
332which will improve client-side NFS
333performance:
334.Bd -literal -offset 4n
335nfs_client_enable="YES"
336.Ed
337.Pp
338Each client should create softlinks for
339.Pa /usr/ports
340and
341.Pa /usr/src
342that point
343into the NFS-mounted environment.
344If a particular client is running -CURRENT,
345.Pa /usr/src
346should be a softlink to
347.Pa /FreeBSD/FreeBSD-current/src .
348If it is running -STABLE,
349.Pa /usr/src
350should be a softlink to
351.Pa /FreeBSD/FreeBSD-4.x/src .
352I do not usually create a
353.Pa /usr/src2
354softlink on
355clients, that is used as a convenient shortcut when working on the source
356code on the master server only and could create massive confusion (of the
357human variety) on a client.
358.Bd -literal -offset 4n
359(ON EACH CLIENT)
360cd /usr
361rm -rf ports src
362ln -s /FreeBSD/FreeBSD-current/ports ports
363ln -s /FreeBSD/FreeBSD-XXX/src src
364.Ed
365.Pp
366Do not forget to create the working directories so you can build ports, as
367previously described.
368If these are not good locations, make them softlinks to the correct location.
369Remember that
370.Pa /usr/ports/distfiles
371is exported by
372the master server and is therefore going to point to the same place
373(typically
374.Pa /usr/ports.distfiles )
375on every machine.
376.Bd -literal -offset 4n
377mkdir /usr/ports.distfiles
378mkdir /usr/ports.workdir
379.Ed
380.Sh BUILDING KERNELS
381Here is how you build a -STABLE kernel (on your main development box).
382If you want to create a custom kernel, copy
383.Pa GENERIC
384to
385.Pa KERNELNAME
386and then edit it before configuring and building.
387The kernel configuration file lives in
388.Pa /usr/src/sys/i386/conf/KERNELNAME .
389.Bd -literal -offset 4n
390cd /usr/src
391make buildkernel KERNCONF=KERNELNAME
392.Ed
393.Pp
394.Sy WARNING!
395If you are familiar with the old config/cd/make method of building
396a -STABLE kernel, note that the
397.Xr config 8
398method will put the build environment in
399.Pa /usr/src/sys/i386/compile/KERNELNAME
400instead of in
401.Pa /usr/obj .
402.Pp
403Building a -CURRENT kernel
404.Bd -literal -offset 4n
405cd /usr/src2		(on the master server)
406make buildkernel KERNCONF=KERNELNAME
407.Ed
408.Sh INSTALLING KERNELS
409Installing a -STABLE kernel (typically done on a client,
410only do this on your main development server if you want to install a new
411kernel for your main development server):
412.Bd -literal -offset 4n
413cd /usr/src
414make installkernel KERNCONF=KERNELNAME
415.Ed
416.Pp
417If you are using the older config/cd/make build mechanism for -STABLE, you
418would install using:
419.Bd -literal -offset 4n
420cd /usr/src/sys/i386/compile/KERNELNAME
421make install
422.Ed
423.Pp
424Installing a -CURRENT kernel (typically done only on a client)
425.Bd -literal -offset 4n
426(remember /usr/src is pointing to the client's specific environment)
427cd /usr/src
428make installkernel KERNCONF=KERNELNAME
429.Ed
430.Sh BUILDING THE WORLD
431This environment is designed such that you do all builds on the master server,
432and then install from each client.
433You can do builds on a client only if
434.Pa /usr/obj
435is local to that client.
436Building the world is easy:
437.Bd -literal -offset 4n
438cd /usr/src
439make buildworld
440.Ed
441.Pp
442If you are on the master server you are running in a -STABLE environment, but
443that does not prevent you from building the -CURRENT world.
444Just
445.Xr cd 1
446into the appropriate source directory and you are set.
447Do not
448accidentally install it on your master server though!
449.Bd -literal -offset 4n
450cd /usr/src2
451make buildworld
452.Ed
453.Sh INSTALLING THE WORLD
454You can build on your main development server and install on clients.
455The main development server must export
456.Pa /FreeBSD
457and
458.Pa /usr/obj
459via read-only NFS to the clients.
460.Pp
461.Em NOTE!!!
462If
463.Pa /usr/obj
464is a softlink on the master server, it must also be the EXACT
465SAME softlink on each client.
466If
467.Pa /usr/obj
468is a directory in
469.Pa /usr
470or a mount point on the master server,
471then it must be (interchangeably) a directory in
472.Pa /usr
473or a mount point on
474each client.
475This is because the
476absolute paths are expected to be the same when building the world as when
477installing it, and you generally build it on your main development box
478and install it from a client.
479If you do not set up
480.Pa /usr/obj
481properly you will not be able to build on
482machine and install on another.
483.Bd -literal -offset 4n
484(ON THE CLIENT)
485(remember /usr/src is pointing to the client's specific environment)
486cd /usr/src
487make installworld
488.Ed
489.Pp
490.Sy WARNING!
491If builds work on the master server but installs do not work from the
492clients, for example you try to install and the client complains that
493the install tried to write into the read-only
494.Pa /usr/obj ,
495then it is likely
496that the
497.Pa /etc/make.conf
498file on the client does not match the one on the
499master server closely enough and the install is trying to install something
500that was not built.
501.Sh DOING DEVELOPMENT ON A CLIENT (NOT JUST INSTALLING)
502Developers often want to run buildkernel's or buildworld's on client
503boxes simply to life-test the box.
504You do this in the same manner that you buildkernel and buildworld on your
505master server.
506All you have to do is make sure that
507.Pa /usr/obj
508is pointing to local storage.
509If you followed my advise and made
510.Pa /usr/obj
511its own partition on the master
512server,
513then it is typically going to be an NFS mount on the client.
514Simply unmounting
515.Pa /usr/obj
516will leave you with a
517.Pa /usr/obj
518that is a
519subdirectory in
520.Pa /usr
521which is typically local to the client.
522You can then do builds to your heart's content!
523.Sh MAINTAINING A LOCAL BRANCH
524I have described how to maintain two versions of the source tree, a stable
525version in
526.Pa /FreeBSD/FreeBSD-4.x
527and a current version in
528.Pa /FreeBSD/FreeBSD-current .
529There is absolutely nothing preventing you
530from breaking out other versions of the source tree
531into
532.Pa /FreeBSD/XXX .
533In fact, my
534.Pa /FreeBSD
535partition also contains
536.Ox ,
537.Nx ,
538and various flavors of
539.Tn Linux .
540You may not necessarily be able to build
541.Pf non- Fx
542operating systems on
543your master server, but being able
544to collect and manage source distributions from a central server is a very
545useful thing to be able to do and you can certainly export to machines
546which can build those other operating systems.
547.Pp
548Many developers choose to maintain a local branch of
549.Fx
550to test patches or build a custom distribution.
551This can be done with CVS or another source code management system
552(SubVersion, Perforce, BitKeeper) with its own repository.
553Since the main
554.Fx
555tree is based on CVS, the former is convenient.
556.Pp
557First, you need to modify your
558.Xr cvsup 1
559environment to avoid it modifying
560the local changes you have committed to the repository.
561It is important to remove the
562.Ic delete
563keyword from your
564.Pa supfile
565and to add the
566.Pa CVSROOT
567subdirectory to your
568.Pa refuse
569file.
570For more information, see
571.Xr cvsup 1 .
572.Pp
573The
574.Fx
575version of
576.Xr cvs 1
577examines a custom environmental variable,
578.Ev CVS_LOCAL_BRANCH_NUM ,
579which specifies an integer to use when doing a
580.Xr cvs 1
581.Cm tag Ns / Ns Cm rtag .
582Set this number to something high (say 1000) to avoid colliding
583with potential future branches of the main repository.
584For example,
585branching a file with version 1.4 produces 1.4.1000.
586Future commits to this branch will produce revisions 1.4.1000.1,
5871.4.1000.2, etc.
588.Pp
589To fork your local branch, do:
590.Bd -literal -offset 4n
591cvs rtag -r RELENG_4 -b LOCAL_RELENG_4 src
592.Ed
593.Pp
594After this, you can check out a copy from your local repository using the
595new tag and begin making changes and committing them.
596For more information on using CVS, see
597.Xr cvs 1 .
598.Pp
599.Sy WARNING!
600The
601.Xr cvsup 1
602utility may blow away changes made on a local branch in
603some situations.
604This has been reported to occur when the master CVS repository is
605directly manipulated or an RCS file is changed.
606At this point,
607.Xr cvsup 1
608notices that the client and server have entirely
609different RCS files, so it does a full replace instead of trying to
610send just deltas.
611Ideally this situation should never arise, but in the real world it
612happens all the time.
613.Pp
614While this is the only scenario where the problem should crop up,
615there have been some suspicious-sounding reports of
616.Ev CVS_LOCAL_BRANCH_NUM
617lossage that cannot be explained by this alone.
618Bottom line is, if you value your local branch then you
619should back it up before every update.
620.Sh UPDATING VIA CVS
621The advantage of using
622.Xr cvsup 1
623to maintain an updated copy of the CVS
624repository instead of using it to maintain source trees directly is that you
625can then pick and choose when you bring your source tree (or pieces of your
626source tree) up to date.
627By using a
628.Xr cron 8
629job to maintain an updated CVS repository, you can update
630your source tree at any time without any network cost as follows:
631.Bd -literal -offset 4n
632(on the main development server)
633cd /usr/src
634cvs -d /home/ncvs update
635cd /usr/src2
636cvs -d /home/ncvs update
637cd /usr/ports
638cvs -d /home/ncvs update
639.Ed
640.Pp
641It is that simple, and since you are exporting the whole lot to your
642clients, your clients have immediate visibility into the updated
643source.
644This is a good time to also remind you that most of the
645.Xr cvs 1
646operations you do will be done as
647.Dq Li root ,
648and that certain options are
649required for CVS to operate properly on the
650.Fx
651repository.
652For example,
653.Fl Pd
654is necessary when running
655.Nm cvs Cm update .
656These options are typically placed in your
657.Pa ~/.cvsrc
658(as already described)
659so you do not have to respecify them every time you run a
660.Xr cvs 1
661command.
662Maintaining the CVS repository also gives you far more flexibility
663in regards to breaking out multiple versions of the source tree.
664It is a good idea to give your
665.Pa /FreeBSD
666partition a lot of space (I recommend
6678-12GB) precisely for that reason.
668If you can make it 15GB I would do it.
669.Pp
670I generally do not
671.Nm cvs Cm update
672via a
673.Xr cron 8
674job.
675This is because I generally want the source to not change out from under me
676when I am developing code.
677Instead I manually update the source every so often...\& when I feel it is
678a good time.
679My recommendation is to only keep the CVS repository synchronized via
680.Xr cron 8 .
681.Sh SEE ALSO
682.Xr crontab 1 ,
683.Xr crontab 5 ,
684.Xr build 7 ,
685.Xr firewall 7 ,
686.Xr release 7 ,
687.Xr tuning 7 ,
688.Xr diskless 8
689.Sh HISTORY
690The
691.Nm
692manual page was originally written by
693.An Matthew Dillon Aq dillon@FreeBSD.org
694and first appeared
695in
696.Fx 5.0 ,
697December 2002.
698