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=500or older if building with a C99 or newer compiler. - You cannot use
_XOPEN_SOURCE=600or 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=500or older will fail with GCC >= 5.x - Code which unconditionally defines
_XOPEN_SOURCE=600or 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
#endifThis 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
#endifIf 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+= c99Care 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=600will 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.