Moving from Linux to FreeBSD involves quite a number of changes; some gains and some losses. As a developer, for most of the programming languages, especially the high level ones, there are no meaningful disturbing changes. But for languages like C (and its sibling C++), if you want to port your softwares, libraries, etc, some points might need to be considered.
As is often the case with C, it is not especially straightforward; the code itself might need some changes, minus the pure POSIX part. Let’s say your program needs to use some known network functions.
#include <sys/param.h> ? BSD defined, FreeBSD current version etc … #if defined(BSD) #include <netinet/in.h> #endif #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> int main(int argc, char *argv[]) { … struct in_addr in; const char *ip = argv[1]; if (inet_pton(AF_INET, ip, &in) == -1) ... }
Here we have a more complex case; for example, how do we get the MAC Address of an interface?
int main(int argc, char *argv[]) {… struct ifreq if; char hwaddr[6] = { 0 }; ... #if defined(__linux__) if (ioctl(clsock, SIOCGIFHWADDR, &if) == 0) memcpy(hwaddr, if.ifr_hwaddr.sa_data, sizeof(hwaddr)); ... #else if defined(BSD) struct sockaddr_dl *cl = (struct sockaddr_dl *)(if.ifa_ addr); unsigned char *p = (unsigned char *)LLADDR(cl); memcpy(hwaddr, p, sizeof(hwaddr)); #endif …}
In addition, FreeBSD provides a bunch of specific functions like strlcpy/strlcat (safer versions of strcpy/strcat) and strtonum family functions, all of which are available in the base whereas Linux must install the separate BSD library to have them. If you have any doubts about any functions, all manpages are available and very well written.
The environment
FreeBSD is shipped by default with clang whereas Linux relies on GCC suite. If you heavily use OpenMP, clang does not provide it yet so you might need to install GCC from ports. Somehow, clang mostly compiles faster and provides more informative warning and error messages. Fortunately, they share a significant amount of common flags.
On Linux, you may use a custom memory allocator during your development like jemalloc. It’s a very handy and useful library which allows you to generate statistics, to fill freed memory with specific values, and to spot corrupted memory usage.
Good news! You do not need to install it—FreeBSD libc’s malloc (aka phkmalloc) uses jemalloc internally. To print statistics from your application, for example, you need to include malloc_np.h
instead of jemalloc/jemalloc.h
.
As for the makefiles, this is the BSD format which differs from GNU style:
A basic makefile for a library:
… LIB= mylib SHLIB_MAJOR= 1 SHLIB_MINOR= 0 => In addition to the static (profiled and non profiled one), it will compile the shared version SRCS= mylib.c .include <bsd.lib.mk> … PROG= myprog => will compile an app called myprog SRCS= main.c prog.c CFLAGS+= -I${.CURDIR}/../mylib => always concatenate cflags, some like fstack-protector, -Qunused-arguments … are added automatically LDADD= -lutil -lmylib DPADD= ${LIBUTIL} => linked to libutil.a ${.CURDIR}/../mylib/libmylib.a .include <bsd.prog.mk>
FreeBSD can handle GNU via (gnu)make, libtool, etc via the ports.
Or to save the effort of porting this part, it might be more handy to use cmake or scons.
The publication
You might want to publish your library / application in pure FreeBSD’s path. You can make a port which can provide some options for the user. It can download the source and compile it with its dependencies in a natural manner. In addition, you can build a binary package to facilitate the distribution. Example of a port Makefile:
PORTNAME= mylib PORTVERSION= 1 PORTREVISION= 0 MAINTAINER= john.doe@email.com LICENSE= BSD OPTIONS_DEFINE= CURL_SUPPORT CURL_SUPPORT_DESC= Enable Curl support => Will display to the user the curl support then will add a flag during compilation .if ${PORT_OPTIONS:MCURL_SUPPORT} CFLAGS+= -DCURL .endif .include <bsd.port.mk>
For instance, you can put the archive .tar.gz of the library in /usr/ports/distfiles
, then type make checksum. Then, make install will compile and install it in /usr/local. The handbook of making ports is very useful to read.
Furthermore, you can build a binary version of this port to facilitate its distribution. Simply as it is, pkg create mylib. It will create a txz archive in the current folder. In the end, pkg install mylib will install it.
The conclusion
Developing under FreeBSD is not the extreme challenge you might think it is. Even better, from coding to publishing, everything is thought out and made in a constant way without any external dependencies. If you even want to go further, like kernel development, again it is easy and in base. So there is no real reason to stay away from FreeBSD anymore, you are more than welcome.
DAVID CARLIER
David Carlier has been working as a software developer since 2001. He used FreeBSD for more than 10 years and starting from this year, he became involved with the HardenedBSD project and performed serious developments on FreeBSD. He worked for a mobile product company that provides C++ APIs for two years in Ireland. From this, he became completely inspired to develop on FreeBSD.