xref: /freebsd/share/man/man7/development.7 (revision dba6dd177bdee890cf445fbe21a5dccefd5de18e)
1.\" Copyright (c) 1998, Matthew Dillon.  Terms and conditions are those of
2.\" the BSD Copyright as specified in the file "/usr/src/COPYRIGHT" in
3.\" the FreeBSD source tree.
4.\"
5.\" $FreeBSD$
6.\"
7.Dd December 21, 2002
8.Dt DEVELOPMENT 7
9.Os
10.Sh NAME
11.Nm development
12.Nd introduction to development with the FreeBSD codebase
13.Sh DESCRIPTION
14This manual page describes how an ordinary sysop,
15.Ux admin, or developer
16can, without any special permission, obtain, maintain, and modify the
17.Fx
18codebase as well as how to maintaining a master build which can
19then be exported to other machines in your network.
20This manual page
21is targeted to system operators, programmers, and developers.
22.Pp
23Please note that what is being described here is based on a complete
24FreeBSD environment, not just the FreeBSD kernel.
25The methods described
26here are as applicable to production installations as it is to development
27environments.
28You need a good 12-17GB of disk space on one machine to make this work
29conveniently.
30.Sh SETTING UP THE ENVIRONMENT ON THE MASTER SERVER
31Your master server should always run a stable, production version of the
32.Fx
33operating system.   This does not prevent you from doing -CURRENT
34builds or development.  The last thing you want to do is to run an
35unstable environment on your master server which could lead to a situation
36where you lose the environment and/or cannot recover from a mistake.
37.Pp
38Create a huge partition called /FreeBSD.
398-12GB is recommended.
40This partition will contain nearly all the development environment,
41including the CVS tree, broken-out source, and possibly even object files.
42You are going to export this partition to your other machines via a
43READ-ONLY NFS export so do not mix it with other more security-sensitive
44partitions.
45.Pp
46You have to make a choice in regards to
47.Pa /usr/obj .
48You can put
49.Pa /usr/obj
50in
51.Pa /FreeBSD
52or you can make
53.Pa /usr/obj
54its own partition.
55I recommend making it a separate partition for several reasons.  First,
56as a safety measure since this partition is written to a great deal.
57Second, because you typically do not have to back it up.
58Third, because it makes it far easier to mix and match the development
59environments which are described later in this document.
60I recommend a
61.Pa /usr/obj
62partition of at least 5GB.
63.Pp
64On the master server, use cvsup to automatically pull down and maintain
65the
66.Fx
67CVS archive once a day.  The first pull will take a long time,
68it is several gigabytes, but once you have it the daily syncs will be quite
69small.
70.Bd -literal -offset 4n
71mkdir /FreeBSD/FreeBSD-CVS
72rm -rf /home/ncvs
73ln -s /FreeBSD/FreeBSD-CVS /home/ncvs
74.Ed
75.Pp
76The cron job should look something like this (please randomize the time of
77day!).
78Note that you can use the cvsup file example directly from
79/usr/share/examples without modification by supplying appropriate arguments
80to cvsup.
81.Bd -literal -offset 4n
8233 6 * * *      /usr/local/bin/cvsup -g -r 20 -L 2 -h cvsup.freebsd.org /usr/share/examples/cvsup/cvs-supfile
83.Ed
84.Pp
85Run the cvsup manually the first time to pull down the archive.  It could take
86all day depending on how fast your connection is!
87You will run all cvsup and cvs operations as root and you need to set
88up a ~/.cvsrc (/root/.cvsrc) file, as shown below, for proper cvs operation.
89Using ~/.cvsrc to specify cvs defaults is an excellent way
90to "file and forget", but you should never forget that you put them in there.
91.Bd -literal -offset 4n
92# cvs -q
93diff -u
94update -Pd
95checkout -P
96.Ed
97.Pp
98Now use cvs to checkout a -STABLE source tree and a -CURRENT source tree,
99as well as ports and docs, to create your initial source environment.
100Keeping the broken-out source and ports in /FreeBSD allows you to export
101it to other machines via read-only NFS.
102This also means you only need to edit/maintain files in one place and all
103your clients automatically pick up the changes.
104.Bd -literal -offset 4n
105mkdir /FreeBSD/FreeBSD-4.x
106mkdir /FreeBSD/FreeBSD-current
107
108cd /FreeBSD/FreeBSD-4.x
109cvs -d /home/ncvs checkout -rRELENG_4 src
110
111cd /FreeBSD/FreeBSD-current
112cvs -d /home/ncvs checkout src
113cvs -d /home/ncvs checkout ports
114cvs -d /home/ncvs checkout doc
115.Ed
116.Pp
117Now create a softlink for /usr/src and /usr/src2.
118On the main server I always point /usr/src at -STABLE and /usr/src2 at
119-CURRENT.  On client machines I usually do not have a /usr/src2 and I make
120/usr/src point at whatever version of FreeBSD the client box is intended to
121run.
122.Bd -literal -offset 4n
123cd /usr
124rm -rf src src2
125ln -s /FreeBSD/FreeBSD-4.x/src src	(could be -CURRENT on a client)
126ln -s /FreeBSD/FreeBSD-current/src src2	(MASTER SERVER ONLY)
127.Ed
128.Pp
129Now you have to make a choice for /usr/obj.
130Well, hopefully you made it already and chose the partition method.  If you
131chose poorly you probably intend to put it in /FreeBSD and, if so, this is
132what you want to do:
133.Bd -literal -offset 4n
134(ONLY IF YOU MADE A POOR CHOICE AND PUT /usr/obj in /FreeBSD!)
135mkdir /FreeBSD/obj
136cd /usr
137rm -rf obj
138ln -s /FreeBSD/obj obj
139.Ed
140.Pp
141Alternatively you may chose simply to leave /usr/obj in /usr.  If your
142/usr is large enough this will work, but I do not recommend it for
143safety reasons (/usr/obj is constantly being modified, /usr is not).
144.Pp
145Note that exporting /usr/obj via read-only NFS to your other boxes will
146allow you to build on your main server and install from your other boxes.
147If you also want to do builds on some or all of the clients you can simply
148have /usr/obj be a local directory on those clients.
149You should never export /usr/obj read-write, it will lead to all sorts of
150problems and issues down the line and presents a security problem as well.
151It is far easier to do builds on the master server and then only do installs
152on the clients.
153.Pp
154I usually maintain my ports tree via CVS.
155It is sitting right there in the master CVS archive and I've even told you
156to check it out (see above).
157With some fancy softlinks you can make the ports tree available both on your
158master server and on all of your other machines.
159Note that the ports tree exists only on the HEAD cvs branch, so its always
160-CURRENT even on a -STABLE box.  This is what you do:
161.Bd -literal -offset 4n
162(THESE COMMANDS ON THE MASTER SERVER AND ON ALL CLIENTS)
163cd /usr
164rm -rf ports
165ln -s /FreeBSD/FreeBSD-current/ports ports
166
167cd /usr/ports   			(this pushes into the softlink)
168rm -rf distfiles			(ON MASTER SERVER ONLY)
169ln -s /usr/ports.distfiles distfiles	(ON MASTER SERVER ONLY)
170
171mkdir /usr/ports.distfiles
172mkdir /usr/ports.workdir
173.Ed
174.Pp
175Since /usr/ports is softlinked into what will be read-only on all of your
176clients, you have to tell the ports system to use a different working
177directory to hold ports builds.
178You want to add a line to your /etc/make.conf file on the master server
179and on all your clients:
180.Bd -literal -offset 4n
181WRKDIRPREFIX=/usr/ports.workdir
182.Ed
183.Pp
184You should try to make the directory you use for the ports working directory
185as well as the directory used to hold distfiles consistent across all of your
186machines.
187If there isn't enough room in /usr/ports.distfiles and /usr/ports.workdir I
188usually make those softlinks (since this is on /usr these are per-machine) to
189where the distfiles and working space really are.
190.Sh EXPORTING VIA NFS FROM THE MASTER SERVER
191The master server needs to export /FreeBSD and /usr/obj via NFS so all the
192rest of your machines can get at them.
193I strongly recommend using a read-only export for both security and safety.
194The environment I am describing in this manual page is designed primarily
195around read-only NFS exports.
196Your exports file on the master server should contain the following lines:
197.Bd -literal -offset 4n
198/FreeBSD -ro -alldirs -maproot=root: -network YOURLAN -mask YOURLANMASK
199/usr/obj -ro -alldirs -maproot=root: -network YOURLAN -mask YOURLANMASK
200.Ed
201.Pp
202Of course, NFS server operations must also be configured on that machine.
203This is typically done via your /etc/rc.conf:
204.Bd -literal -offset 4n
205nfs_server_enable="YES"
206nfs_server_flags="-u -t -n 4"
207.Ed
208.Sh THE CLIENT ENVIRONMENT
209All of your client machines can import the development/build environment
210directory simply by NFS mounting /FreeBSD and /usr/obj from the master
211server.
212A typical /etc/fstab entry on your client machines will be something like this:
213.Bd -literal -offset 4n
214masterserver:/FreeBSD     /FreeBSD        nfs     ro,bg    0       0
215masterserver:/usr/obj     /usr/obj        nfs     ro,bg    0       0
216.Ed
217.Pp
218And, of course, you should configure the client for NFS client operations
219via /etc/rc.conf.
220In particular, this will turn on nfsiod which will improve client-side NFS
221performance:
222.Bd -literal -offset 4n
223nfs_client_enable="YES"
224.Ed
225.Pp
226Each client should create softlinks for /usr/ports and /usr/src that point
227into the NFS-mounted environment.
228If a particular client is running -CURRENT, /usr/src
229should be a softlink to /FreeBSD/FreeBSD-current/src.
230If it is running -STABLE, /usr/src should be a softlink to
231/FreeBSD/FreeBSD-4.x/src.  I do not usually create a /usr/src2 softlink on
232clients, that is used as a convenient shortcut when working on the source
233code on the master server only and could create massive confusion (of the
234human variety) on a client.
235.Bd -literal -offset 4n
236(ON EACH CLIENT)
237cd /usr
238rm -rf ports src
239ln -s /FreeBSD/FreeBSD-current/ports ports
240ln -s /FreeBSD/FreeBSD-XXX/src src
241.Ed
242.Pp
243Don't forget to create the working directories so you can build ports, as
244previously described.
245If these are not good locations, make them softlinks to the correct location.
246Remember that /usr/ports/distfiles is exported by
247the master server and is therefore going to point to the same place
248(typically /usr/ports.distfiles) on every machine.
249.Bd -literal -offset 4n
250mkdir /usr/ports.distfiles
251mkdir /usr/ports.workdir
252.Ed
253.Sh BUILDING KERNELS
254Here is how you build a -STABLE kernel (on your main development box).
255If you want to create a custom kernel, cp GENERIC to YOURKERNEL and then
256edit it before configuring and building.
257The kernel configuration file lives in /usr/src/sys/i386/conf/KERNELNAME.
258.Bd -literal -offset 4n
259cd /usr/src
260make buildkernel KERNCONF=KERNELNAME
261.Ed
262.Pp
263.Sy WARNING!
264If you are familiar with the old config/cd/make method of building
265a -STABLE kernel, note that the config method will put the build
266environment in /usr/src/sys/compile/KERNELNAME instead of in /usr/obj.
267.Pp
268Building a -CURRENT kernel
269.Bd -literal -offset 4n
270cd /usr/src2		(on the master server)
271make buildkernel KERNCONF=KERNELNAME
272.Ed
273.Sh INSTALLING KERNELS
274Installing a -STABLE kernel (typically done on a client.
275Only do this on your main development server if you want to install a new
276kernel for your main development server):
277.Bd -literal -offset 4n
278cd /usr/src
279make installkernel KERNCONF=KERNELNAME
280.Ed
281.Pp
282If you are using the older config/cd/make build mechanism for stable, you
283would install using:
284.Bd -literal -offset 4n
285cd /usr/src/sys/compile/KERNELNAME
286make install
287.Ed
288.Pp
289Installing a -CURRENT kernel (typically done only on a client)
290.Bd -literal -offset 4n
291(remember /usr/src is pointing to the client's specific environment)
292cd /usr/src
293make installkernel KERNCONF=KERNELNAME
294.Ed
295.Pp
296.Sh BUILDING THE WORLD
297This environment is designed such that you do all builds on the master server,
298and then install from each client.
299You can do builds on a client only if /usr/obj is local to that client.
300Building the world is easy:
301.Bd -literal -offset 4n
302cd /usr/src
303make buildworld
304.Ed
305.Pp
306If you are on the master server you are running in a -STABLE environment, but
307that does not prevent you from building the -CURRENT world.
308Just cd into the appropriate source directory and you are set.  Do not
309accidentally install it on your master server though!
310.Bd -literal -offset 4n
311cd /usr/src2
312make buildworld
313.Ed
314.Sh INSTALLING THE WORLD
315You can build on your main development server and install on clients.
316The main development server must export /FreeBSD and /usr/obj via
317read-only NFS to the clients.
318.Pp
319.Em NOTE!!!
320If /usr/obj is a softlink on the master server, it must also be the EXACT
321SAME softlink on each client.
322If /usr/obj is a directory in /usr or a mount point on the master server,
323then it must be (interchangeably) a directory in /usr or a mount point on
324each client.
325This is because the
326absolute paths are expected to be the same when building the world as when
327installing it, and you generally build it on your main development box
328and install it from a client.
329If you do not setup /usr/obj properly you will not be able to build on
330machine and install on another.
331.Bd -literal -offset 4n
332(ON THE CLIENT)
333(remember /usr/src is pointing to the client's specific environment)
334cd /usr/src
335make installworld
336.Ed
337.Pp
338.Sy WARNING!
339If builds work on the master server but installs do not work from the
340clients, for example you try to install and the client complains that
341the install tried to write into the read-only /usr/obj, then it is likely
342that the /etc/make.conf file on the client does not match the one on the
343master server closely enough and the install is trying to install something
344that was not built.
345.Sh DOING DEVELOPMENT ON A CLIENT (NOT JUST INSTALLING)
346Developers often want to run buildkernel's or buildworld's on client
347boxes simply to life-test the box.
348You do this in the same manner that you buildkernel and buildworld on your
349master server.
350All you have to do is make sure that /usr/obj is pointing to local storage.
351If you followed my advise and made /usr/obj its own partition on the master
352server,
353then it is typically going to be an NFS mount on the client.
354Simply unmounting /usr/obj will leave you with a /usr/obj that is a
355subdirectory in /usr which is typically local to the client.
356You can then do builds to your heart's content!
357.Sh MAINTAINING A LOCAL BRANCH
358I have described how to maintain two versions of the source tree, a stable
359version in /FreeBSD/FreeBSD-4.x and a current version
360in /FreeBSD/FreeBSD-current.
361There is absolutely nothing preventing you
362from breaking out other versions of the source tree
363into /FreeBSD/XXX.
364In fact, my /FreeBSD partition also contains
365.Ox ,
366.Nx ,
367and various flavors of Linux.
368You may not necessarily be able to build non-FreeBSD operating systems on
369your master server, but being able
370to collect and manage source distributions from a central server is a very
371useful thing to be able to do and you can certainly export to machines
372which can build those other operating systems.
373.Pp
374Many developers choose to maintain a local branch of
375.Fx
376to test patches or build a custom distribution.
377This can be done with CVS or another source code management system
378(SubVersion, Perforce, BitKeeper) with its own repository.
379Since the main
380.Fx
381tree is based on CVS, the former is convenient.
382.Pp
383First, you need to modify your cvsup environment to avoid it modifying
384the local changes you have committed to the repository.
385It is important to remove the "delete" keyword from your supfile and to
386add the CVSROOT subdirectory to your refuse file.
387For more information, see
388.Xr cvsup 1 .
389.Pp
390The
391.Fx
392version of CVS examines a custom environmental variable,
393CVS_LOCAL_BRANCH_NUM, which specifies an integer to use when doing a cvs
394tag/rtag.
395Set this number to something high (say 1000) to avoid colliding
396with potential future branches of the main repository.  For example,
397branching a file with version 1.4 produces 1.4.1000.
398Future commits to this branch will produce revisions 1.4.1000.1,
3991.4.1000.2, etc.
400.Pp
401To fork your local branch, do:
402.Bd -literal -offset 4n
403cvs rtag -r RELENG_4 -b LOCAL_RELENG_4 src
404.Ed
405.Pp
406After this, you can check out a copy from your local repository using the
407new tag and begin making changes and committing them.
408For more information on using cvs, see
409.Xr cvs 1 .
410.Pp
411.Sy WARNING!
412The cvsup utility may blow away changes made on a local branch in
413some situations.
414This has been reported to occur when the master CVS repository is
415directly manipulated or an RCS file is changed.
416At this point, cvsup notices that the client and server have entirely
417different RCS files, so it does a full replace instead of trying to
418send just deltas.
419Ideally this situation should never arise, but in the real world it
420happens all the time.
421.Pp
422While this is the only scenario where the problem should crop up,
423there have been some suspicious-sounding reports of
424CVS_LOCAL_BRANCH_NUM lossage that can't be explained by this alone.
425Bottom line is, if you value your local branch then you
426should back it up before every update.
427.Sh UPDATING VIA CVS
428The advantage of using cvsup to maintain an updated copy of the CVS
429repository instead of using it to maintain source trees directly is that you
430can then pick and choose when you bring your source tree (or pieces of your
431source tree) up to date.
432By using a cron job to maintain an updated CVS repository, you can update
433your source tree at any time without any network cost as follows:
434.Bd -literal -offset 4n
435(on the main development server)
436cd /usr/src
437cvs -d /home/ncvs update
438cd /usr/src2
439cvs -d /home/ncvs update
440cd /usr/ports
441cvs -d /home/ncvs update
442.Ed
443.Pp
444It is that simple, and since you are exporting the whole lot to your
445clients, your clients have immediately visibility into the updated
446source.
447This is a good time to also remind you that most of the cvs operations
448you do will be done as root, and that certain options are
449required for CVS to operate properly on the
450.Fx
451repository.  For example,
452.Fl Pd
453is necessary when running "cvs update".
454These options are typically placed in your ~/.cvsrc (as already described)
455so you do not have to respecify them every time you run a CVS command.
456Maintaining the CVS repository also gives you far more flexibility
457in regards to breaking out multiple versions of the source tree.
458It is a good idea to give your /FreeBSD partition a lot of space (I recommend
4598-12GB) precisely for that reason.
460If you can make it 15GB I would do it.
461.Pp
462I generally do not cvs update via a cron job.
463This is because I generally want the source to not change out from under me
464when I am developing code.
465Instead I manually update the source every so often... when I feel it is
466a good time.
467My recommendation is to only keep the cvs repository synchronized via cron.
468.Sh SEE ALSO
469.Xr crontab 1 ,
470.Xr crontab 5 ,
471.Xr build 7 ,
472.Xr firewall 7 ,
473.Xr release 7 ,
474.Xr tuning 7 ,
475.Xr diskless 8
476.Sh HISTORY
477The
478.Nm
479manual page was originally written by
480.An Matthew Dillon Aq dillon@FreeBSD.org
481and first appeared
482in
483.Fx 5.0 ,
484December 2002.
485