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