This is a work-in-progress, but aims to help navigate the murky waters
of setting _XOPEN_SOURCE
in such a way that it is compatible across C
standards on SunOS systems.
A table is worth a thousand words. Defines used in a default compilation
environment (i.e. no -std=..
specified):
Define | GCC 4.x (C90) or older | GCC 5.x (C99) or newer |
---|---|---|
_XOPEN_SOURCE=500 |
Ok | Error |
_XOPEN_SOURCE=600 |
Error | Ok |
_POSIX_SOURCE |
Ok | Error |
_POSIX_C_SOURCE=199506L |
Ok | Error |
_POSIX_C_SOURCE=200112L |
Error | Ok |
__EXTENSIONS__ |
Ok | Ok |
The basic problem boils down to this:
- You cannot use
_XOPEN_SOURCE=500
or older if building with a C99 or newer compiler. - You cannot use
_XOPEN_SOURCE=600
or newer if building with a C90 or older compiler.
The problem is exacerbated by different compiler defaults, meaning that the same piece of code may break depending on which version of GCC you are using:
- GCC <= 4.x default to C90 or older.
- GCC >= 5.x default to C99 or newer.
Thus:
- Code which unconditionally defines
_XOPEN_SOURCE=500
or older will fail with GCC >= 5.x - Code which unconditionally defines
_XOPEN_SOURCE=600
or newer will fail with GCC <= 4.x
An alternative selection of standards is done by _POSIX_C_SOURCE
, and this
generally falls into the same issues:
_POSIX_C_SOURCE=199506L
(if set) or older must be used for C90 or older_POSIX_C_SOURCE=200112L
(if set) or newer must be used for C99 or newer
The normal way we can resolve this is by testing for __STDC_VERSION__
and handle accordingly.
#if __STDC_VERSION__ - 0 < 199901L
#define _XOPEN_SOURCE 500
#else
#define _XOPEN_SOURCE 600
#endif
This however may not be appropriate in all situations. Some OS may behave
differently if _XOPEN_SOURCE
is set compared to the OS defaults, so care
must be taken.
Generally the rule will be that if _XOPEN_SOURCE
is already being set, then
the above should be safe. However if it is being added, then it's probably
worth wrapping it inside a __sun
section:
#if defined(__sun)
# if __STDC_VERSION__ - 0 < 199901L
#define _XOPEN_SOURCE 500
# else
#define _XOPEN_SOURCE 600
# endif
#endif
If the software has hardcoded _XOPEN_SOURCE=600
then the simplest
fix, at least in a pkgsrc environment, is to ensure the software is
built in a C99 environment by setting USE_LANGUAGES
:
USE_LANGUAGES+= c99
Care should be taken if this is set in a public header, as then every dependency will also need C99.
If the software requires adding _XOPEN_SOURCE=600
and does not already
set _XOPEN_SOURCE
in the source, then
USE_LANGUAGES+= c99
CPPFLAGS.SunOS+= -D_XOPEN_SOURCE=600
will avoid the need for patching.
Adding __EXTENSIONS__
to expose additional features should be safe in
any C environment.
Setting _XOPEN_SOURCE_EXTENDED
effectively ignores what _XOPEN_SOURCE
is set to and forces XPG4v2 mode.
This is wrong. Don't ever set it.