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