Mail Archives: cygwin/2003/03/07/13:50:33
I recently re-ran setup.exe and upgraded the packages I have installed and
was surprised to find that many of my projects no longer build with Cygwin.
They now fail with an error regarding the redefinition of struct option.
These projects use getopt_long() which is of course not portable; so I
provide an implementation (copied from NetBSD) along with my other project
source files and #include “getopt.h” where necessary. (Yes, ideally I should
have a ./configure and use the system’s copy if it provides one, but I still
don’t understand why it’s declared in <unistd.h>.) The problem occurs when
<unistd.h> is also #included as it now also provides a definition of struct
option. (Cygwin’s getopt.h and the getopt.h in my projects use different
guard macros.)
For reference, I’ll quote the entire contents of <unistd.h>:
---- cut here ----
/* unistd.h for Cygwin. */
#ifndef _UNISTD_H_
#define _UNISTD_H_
# include <sys/unistd.h>
# define __UNISTD_GETOPT__
# include <getopt.h>
# undef __UNISTD_GETOPT__
#endif /* _UNISTD_H_ */
---- cut here ----
It seems that previously <sys/unistd.h> provided declarations for getopt()
and its associated ints (but *not* for getopt_long() and its associated
paraphernalia) and now it just #includes <getopt.h> when __CYGWIN__ is
defined. Which is weird because <unistd.h> also #includes <getopt.h>. But
when <unistd.h> includes <getopt.h> it uses some preprocessor magic to avoid
declaring getopt_long(); or rather it tries to, as that magic is now
rendered useless by the previous inclusion of <getopt.h>.
I checked glibc 2.3.1’s <unistd.h> and it uses a similar preprocessor
mechanism to declare getopt() (but not getopt_long()) by including
<getopt.h>.
So my question is why does <unistd.h> declare getopt_long()? What precedent
is there for declaring getopt_long() in <unistd.h>? Normally, if you want
getopt_long() you have to #include <getopt.h>.
Checking the CVS log I see that the change (to <sys/unistd.h>) was made on
Sat Dec 28 23:20:47 2002 UTC by cgf with the following log entry:
* libc/include/sys/unistd.h: Under cygwin, just include getopt.h rather than
defining getopt directly.
newlib’s <sys/unistd.h> contains declarations for getopt() and I understand
the desire to not duplicate the declarations in Cygwin’s <getopt.h>, but
<getopt.h> is now included twice every time you #include <unistd.h>. Given
this and the, AFAICT, unprecedented namespace pollution, I propose the
following patch:
--- sys/unistd.h.orig 2003-02-08 12:11:52.000000000 -0500
+++ sys/unistd.h 2003-03-07 07:22:00.000000000 -0500
@@ -125,9 +125,7 @@
int _EXFUN(vhangup, (void ));
_READ_WRITE_RETURN_TYPE _EXFUN(write, (int __fd, const void *__buf, size_t
__nbyte ));
-#ifdef __CYGWIN__
-# include <getopt.h>
-#else
+#ifndef __CYGWIN__
extern char *optarg; /* getopt(3) external variables */
extern int optind, opterr, optopt;
int getopt(int, char * const [], const char *);
Cheers
_________________________________________________________________
Add photos to your messages with MSN 8. Get 2 months FREE*.
http://join.msn.com/?page=features/featuredemail
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -