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