Hi. One of my patches submitted this week is breaking build on BSD systems. I dug deeper and found out that it's because I'm using IPPROTO_* macros from <netinet/in.h> in a header (rte_ip.h) which is included in the driver which uses _XOPEN_SOURCE definition in its Makefile/meson.build.
On Linux and glibc this is not a problem, because: 1. Those IPPROTO macros are included unconditionally and 2. We're using _GNU_SOURCE at top level anyway which gives us visibility of every feature set. According to "features.h" from glibc 2.18 (used in Ubuntu 18.04): https://github.molgen.mpg.de/git-mirror/glibc/blob/release/2.18/master/include/features.h /* If _GNU_SOURCE was defined by the user, turn on all the other features. */ #ifdef _GNU_SOURCE # undef _ISOC95_SOURCE # define _ISOC95_SOURCE 1 # undef _ISOC99_SOURCE # define _ISOC99_SOURCE 1 # undef _ISOC11_SOURCE # define _ISOC11_SOURCE 1 # undef _POSIX_SOURCE # define _POSIX_SOURCE 1 # undef _POSIX_C_SOURCE # define _POSIX_C_SOURCE 200809L # undef _XOPEN_SOURCE # define _XOPEN_SOURCE 700 # undef _XOPEN_SOURCE_EXTENDED # define _XOPEN_SOURCE_EXTENDED 1 # undef _LARGEFILE64_SOURCE # define _LARGEFILE64_SOURCE 1 # undef _BSD_SOURCE # define _BSD_SOURCE 1 # undef _SVID_SOURCE # define _SVID_SOURCE 1 # undef _ATFILE_SOURCE # define _ATFILE_SOURCE 1 #endif BSD systems are a little bit more orthodox: 1. IPPROTOs are defined conditionally if __BSD_VISIBLE macro is defined. If I understand it correctly, they are not a part of any POSIX specification and that's why they are kept separated. 2. __BSD_VISIBLE is set to 0 if any of XOPEN_SOURCE or POSIX_C_SOURCE macros are defined. The reasoning here is: if you don't specify feature set you want to use you have it all, but when you do, you have exactly what you've explicitly asked for. Using XOPEN_SOURCE=700 means: give me POSIX 2k8 and XSI only. In other words using this macro alone is restricting portability; by default DPDK is building with full visibility. https://github.com/freebsd/freebsd/blob/release/12.0.0/sys/sys/cdefs.h Lines 680 to 765 /* Deal with various X/Open Portability Guides and Single UNIX Spec. */ #ifdef _XOPEN_SOURCE #if _XOPEN_SOURCE - 0 >= 700 #define __XSI_VISIBLE 700 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809 #elif _XOPEN_SOURCE - 0 >= 600 #define __XSI_VISIBLE 600 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112 #elif _XOPEN_SOURCE - 0 >= 500 #define __XSI_VISIBLE 500 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199506 #endif #endif /* * Deal with all versions of POSIX. The ordering relative to the tests above is * important. */ #if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) #define _POSIX_C_SOURCE 198808 #endif #ifdef _POSIX_C_SOURCE #if _POSIX_C_SOURCE >= 200809 #define __POSIX_VISIBLE 200809 #define __ISO_C_VISIBLE 1999 #elif _POSIX_C_SOURCE >= 200112 #define __POSIX_VISIBLE 200112 #define __ISO_C_VISIBLE 1999 #elif _POSIX_C_SOURCE >= 199506 #define __POSIX_VISIBLE 199506 #define __ISO_C_VISIBLE 1990 #elif _POSIX_C_SOURCE >= 199309 #define __POSIX_VISIBLE 199309 #define __ISO_C_VISIBLE 1990 #elif _POSIX_C_SOURCE >= 199209 #define __POSIX_VISIBLE 199209 #define __ISO_C_VISIBLE 1990 #elif _POSIX_C_SOURCE >= 199009 #define __POSIX_VISIBLE 199009 #define __ISO_C_VISIBLE 1990 #else #define __POSIX_VISIBLE 198808 #define __ISO_C_VISIBLE 0 #endif /* _POSIX_C_SOURCE */ #else <----- !!! /*- * Deal with _ANSI_SOURCE: * If it is defined, and no other compilation environment is explicitly * requested, then define our internal feature-test macros to zero. This * makes no difference to the preprocessor (undefined symbols in preprocessing * expressions are defined to have value zero), but makes it more convenient for * a test program to print out the values. * * If a program mistakenly defines _ANSI_SOURCE and some other macro such as * _POSIX_C_SOURCE, we will assume that it wants the broader compilation * environment (and in fact we will never get here). */ #if defined(_ANSI_SOURCE) /* Hide almost everything. */ #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 1990 #define __EXT1_VISIBLE 0 #elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */ #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 1999 #define __EXT1_VISIBLE 0 #elif defined(_C11_SOURCE) /* Localism to specify strict C11 env. */ #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 2011 #define __EXT1_VISIBLE 0 #else /* Default environment: show everything. */ By default DPDK falls here: #define __POSIX_VISIBLE 200809 #define __XSI_VISIBLE 700 #define __BSD_VISIBLE 1 #define __ISO_C_VISIBLE 2011 #define __EXT1_VISIBLE 1 #endif #endif To summarize we have different visibility sets for Linux and BSD when using XOPEN_SOURCE or POSIX_C_SOURCE explicitly. To overcome this situation we can either remove problematic XOPEN macros from mk/meson rules (drivers/net/failsafe, drivers/net/mlx4, drivers/net/mlx5) or add explicit -D__BSD_VISIBLE when building for BSD. I think also that defining _GNU_SOURCE for BSD builds makes no sense although it does not cause any problems. I have checked that removing those problematic macros solves build problems on FreeBSD12 and does not break on Ubuntu 18.04. I'd appreciate your thoughts on this topic. Regards, Marcin.