headers: Make getopt.h react to _BSD_SOURCE after being included once first

getopt.h is transitively included by unistd.h, which means that
users who include unistd.h (also potentially unintentionally as
a transitive dependency) won't be able to get "optreset" declared,
if they do e.g. this:

    #include <unistd.h>
    #define _BSD_SOURCE
    #include <getopt.h>

This recently broke building LLDB with latest nightly libc++ headers,
as libc++ headers would end up including unistd.h, while LLDB
later would define _BSD_SOURCE right before including getopt.h.

For definitions like _BSD_SOURCE, the most failsafe solution
generally is to define them before including any header, to avoid
this kind of issue. However, allowing getopt.h to react to
being reincluded with _BSD_SOURCE defined, is quite straightforward.

This allows fixing a recent LLDB build break reported at
https://github.com/llvm/llvm-project/issues/76050.

Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Martin Storsjö 2023-12-20 15:27:09 +02:00
parent 883cc25d70
commit 940e8faa94

View File

@ -28,16 +28,6 @@ extern char *optarg; /* pointer to argument of current option */
extern int getopt(int nargc, char * const *nargv, const char *options); extern int getopt(int nargc, char * const *nargv, const char *options);
#ifdef _BSD_SOURCE
/*
* BSD adds the non-standard `optreset' feature, for reinitialisation
* of `getopt' parsing. We support this feature, for applications which
* proclaim their BSD heritage, before including this header; however,
* to maintain portability, developers are advised to avoid it.
*/
# define optreset __mingw_optreset
extern int optreset;
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@ -52,6 +42,18 @@ extern int optreset;
*/ */
#endif /* !defined(__GETOPT_H__) */ #endif /* !defined(__GETOPT_H__) */
#if !defined(__GETOPT_BSD_H__) && defined(_BSD_SOURCE)
#define __GETOPT_BSD_H__
/*
* BSD adds the non-standard `optreset' feature, for reinitialisation
* of `getopt' parsing. We support this feature, for applications which
* proclaim their BSD heritage, before including this header; however,
* to maintain portability, developers are advised to avoid it.
*/
# define optreset __mingw_optreset
extern int optreset;
#endif /* !defined(__GETOPT_BSD_H__) && defined(_BSD_SOURCE) */
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) #if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__ #define __GETOPT_LONG_H__