[dpdk-dev] Using _XOPEN_SOURCE macros may break builds on FreeBSD

Smoczynski, MarcinX marcinx.smoczynski at intel.com
Fri May 10 19:14:44 CEST 2019


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.


More information about the dev mailing list