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