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