You may come across code that needs modifications or conditional compilation based upon what version of Unix it is running under. If you need to make such changes to the code for conditional compilation, make sure you make the changes as general as possible so that we can back-port code to FreeBSD 1.x systems and cross-port to other BSD systems such as 4.4BSD from CSRG, BSD/386, 386BSD, NetBSD, and OpenBSD.
The preferred way to tell 4.3BSD/Reno (1990) and newer versions of the BSD code apart is by using the BSD macro defined in <sys/param.h>. Hopefully that file is already included; if not, add the code:
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endif
to the proper place in the .c file. We believe that every system that defines these two symbols has sys/param.h. If you find a system that does not, we would like to know. Please send mail to the FreeBSD ports mailing list <freebsd-ports@FreeBSD.org>.
Another way is to use the GNU Autoconf style of doing this:
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
Do not forget to add -DHAVE_SYS_PARAM_H to the CFLAGS in the Makefile for this method.
Once you have sys/param.h included, you may use:
#if (defined(BSD) && (BSD >= 199103))
to detect if the code is being compiled on a 4.3 Net2 code base or newer (e.g. FreeBSD 1.x, 4.3/Reno, NetBSD 0.9, 386BSD, BSD/386 1.1 and below).
Use:
#if (defined(BSD) && (BSD >= 199306))
to detect if the code is being compiled on a 4.4 code base or newer (e.g. FreeBSD 2.x, 4.4, NetBSD 1.0, BSD/386 2.0 or above).
The value of the BSD macro is 199506 for the 4.4BSD-Lite2 code base. This is stated for informational purposes only. It should not be used to distinguish between versions of FreeBSD based only on 4.4-Lite vs. versions that have merged in changes from 4.4-Lite2. The __FreeBSD__ macro should be used instead.
Use sparingly:
__FreeBSD__ is defined in all versions of FreeBSD. Use it if the change you are making only affects FreeBSD. Porting gotchas like the use of sys_errlist[] vs strerror() are Berkeleyisms, not FreeBSD changes.
In FreeBSD 2.x, __FreeBSD__ is defined to be 2. In earlier versions, it is 1. Later versions will bump it to match their major version number.
If you need to tell the difference between a FreeBSD 1.x system and a FreeBSD 2.x or 3.x system, usually the right answer is to use the BSD macros described above. If there actually is a FreeBSD specific change (such as special shared library options when using ld) then it is OK to use __FreeBSD__ and #if __FreeBSD__ > 1 to detect a FreeBSD 2.x and later system. If you need more granularity in detecting FreeBSD systems since 2.0-RELEASE you can use the following:
#if __FreeBSD__ >= 2
#include <osreldate.h>
# if __FreeBSD_version >= 199504
/* 2.0.5+ release specific code here */
# endif
#endif
| Release | __FreeBSD_version |
|---|---|
| 2.0-RELEASE | 119411 |
| 2.1-CURRENT | 199501, 199503 |
| 2.0.5-RELEASE | 199504 |
| 2.2-CURRENT before 2.1 | 199508 |
| 2.1.0-RELEASE | 199511 |
| 2.2-CURRENT before 2.1.5 | 199512 |
| 2.1.5-RELEASE | 199607 |
| 2.2-CURRENT before 2.1.6 | 199608 |
| 2.1.6-RELEASE | 199612 |
| 2.1.7-RELEASE | 199612 |
| 2.2-RELEASE | 220000 |
| 2.2.1-RELEASE | 220000 (no change) |
| 2.2-STABLE after 2.2.1-RELEASE | 220000 (no change) |
| 2.2-STABLE after texinfo-3.9 | 221001 |
| 2.2-STABLE after top | 221002 |
| 2.2.2-RELEASE | 222000 |
| 2.2-STABLE after 2.2.2-RELEASE | 222001 |
| 2.2.5-RELEASE | 225000 |
| 2.2-STABLE after 2.2.5-RELEASE | 225001 |
| 2.2-STABLE after ldconfig -R merge | 225002 |
| 2.2.6-RELEASE | 226000 |
| 2.2.7-RELEASE | 227000 |
| 2.2-STABLE after 2.2.7-RELEASE | 227001 |
| 2.2-STABLE after semctl(2) change | 227002 |
| 2.2.8-RELEASE | 228000 |
| 2.2-STABLE after 2.2.8-RELEASE | 228001 |
| 3.0-CURRENT before mount(2) change | 300000 |
| 3.0-CURRENT after mount(2) change | 300001 |
| 3.0-CURRENT after semctl(2) change | 300002 |
| 3.0-CURRENT after ioctl arg changes | 300003 |
| 3.0-CURRENT after ELF conversion | 300004 |
| 3.0-RELEASE | 300005 |
| 3.0-CURRENT after 3.0-RELEASE | 300006 |
| 3.0-STABLE after 3/4 branch | 300007 |
| 3.1-RELEASE | 310000 |
| 3.1-STABLE after 3.1-RELEASE | 310001 |
| 3.1-STABLE after C++ constructor/destructor order change | 310002 |
| 3.2-RELEASE | 320000 |
| 3.2-STABLE | 320001 |
| 3.2-STABLE after binary-incompatible IPFW and socket changes | 320002 |
| 3.3-RELEASE | 330000 |
| 3.3-STABLE | 330001 |
| 3.3-STABLE after adding mkstemp(3) to libc | 330002 |
| 3.4-RELEASE | 340000 |
| 3.4-STABLE | 340001 |
| 4.0-CURRENT after 3.4 branch | 400000 |
| 4.0-CURRENT after change in dynamic linker handling | 400001 |
| 4.0-CURRENT after C++ constructor/destructor order change | 400002 |
| 4.0-CURRENT after functioning dladdr(3) | 400003 |
| 4.0-CURRENT after __deregister_frame_info dynamic linker bug fix (also 4.0-CURRENT after EGCS 1.1.2 integration) | 400004 |
| 4.0-CURRENT after suser(9) API change (also 4.0-CURRENT after newbus) | 400005 |
| 4.0-CURRENT after cdevsw registration change | 400006 |
| 4.0-CURRENT after the addition of so_cred for socket level credentials | 400007 |
| 4.0-CURRENT after the addition of a poll syscall wrapper to libc_r | 400008 |
| 4.0-CURRENT after the change of the kernel's dev_t type to struct specinfo pointer | 400009 |
| 4.0-CURRENT after fixing a hole in jail(2) | 400010 |
| 4.0-CURRENT after the sigset_t datatype change | 400011 |
| 4.0-CURRENT after the cutover to the GCC 2.95.2 compiler | 400012 |
| 4.0-CURRENT after adding pluggable linux-mode ioctl handlers | 400013 |
| 4.0-CURRENT after importing OpenSSL | 400014 |
| 4.0-CURRENT after the C++ ABI change in GCC 2.95.2 from -fvtable-thunks to -fno-vtable-thunks by default | 400015 |
| 4.0-CURRENT after importing OpenSSH | 400016 |
| 4.0-RELEASE | 400017 |
| 4.0-STABLE after 4.0-RELEASE | 400018 |
| 4.0-STABLE after merging libxpg4 code into libc. | 400020 |
| 4.0-STABLE after upgrading Binutils to 2.10.0, ELF branding changes, and tcsh in the base system. | 400021 |
| 4.1-RELEASE | 410000 |
| 4.1-STABLE after 4.1-RELEASE | 410001 |
| 4.1-STABLE after setproctitle(3) moved from libutil to libc. | 410002 |
| 4.1.1-RELEASE | 411000 |
| 4.1.1-STABLE after 4.1.1-RELEASE | 411001 |
| 4.2-RELEASE | 420000 |
| 4.2-STABLE after combining libgcc.a and libgcc_r.a, and associated GCC linkage changes. | 420001 |
| 5.0-CURRENT | 500000 |
| 5.0-CURRENT after adding addition ELF header fields, and changing our ELF binary branding method. | 500001 |
| 5.0-CURRENT after kld metadata changes. | 500002 |
| 5.0-CURRENT after buf/bio changes. | 500003 |
| 5.0-CURRENT after binutils upgrade. | 500004 |
| 5.0-CURRENT after merging libxpg4 code into libc and after TASKQ interface introduction. | 500005 |
| 5.0-CURRENT after the addition of AGP interfaces. | 500006 |
| 5.0-CURRENT after Perl upgrade to 5.6.0 | 500007 |
| 5.0-CURRENT after the update of KAME code to 2000/07 sources. | 500008 |
| 5.0-CURRENT after ether_ifattach() and ether_ifdetach() changes. | 500009 |
| 5.0-CURRENT after changing mtree defaults back to original variant, adding -L to follow symlinks. | 500010 |
| 5.0-CURRENT after kqueue API changed. | 500011 |
| 5.0-CURRENT after setproctitle(3) moved from libutil to libc. | 500012 |
| 5.0-CURRENT after the first SMPng commit. | 500013 |
| 5.0-CURRENT after <sys/select.h> moved to <sys/selinfo.h>. | 500014 |
| 5.0-CURRENT after combining libgcc.a and libgcc_r.a, and associated GCC linkage changes. | 500015 |
| 5.0-CURRENT after change allowing libc and libc_r to be linked together, deprecating -pthread option. | 500016 |
| 5.0-CURRENT after switch from struct ucred to struct xucred to stabilize kernel-exported API for mountd et al. | 500017 |
| 5.0-CURRENT after addition of CPUTYPE make variable for controlling CPU-specific optimizations. | 500018 |
| 5.0-CURRENT after moving machine/ioctl_fd.h to sys/fdcio.h | 500019 |
| 5.0-CURRENT after locale names renaming. | 500020 |
| 5.0-CURRENT after Bzip2 import. | 500021 |
| 5.0-CURRENT after SSE support. | 500022 |
Note: Note that 2.2-STABLE sometimes identifies itself as ``2.2.5-STABLE'' after the 2.2.5-RELEASE. The pattern used to be year followed by the month, but we decided to change it to a more straightforward major/minor system starting from 2.2. This is because the parallel development on several branches made it infeasible to classify the releases simply by their real release dates. If you are making a port now, you do not have to worry about old -CURRENTs; they are listed here just for your reference.
In the hundreds of ports that have been done, there have only been one or two cases where __FreeBSD__ should have been used. Just because an earlier port screwed up and used it in the wrong place does not mean you should do so too.