bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-gnulib] Re: getopt trouble on uClibc systems


From: Simon Josefsson
Subject: [Bug-gnulib] Re: getopt trouble on uClibc systems
Date: Thu, 01 Jul 2004 18:24:36 +0200
User-agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3.50 (gnu/linux)

Here's a first attempt.  The important part from getopt.m4 is:

  GETOPT_H=
  AC_CHECK_HEADERS([getopt.h], [], [GETOPT_H=getopt.h])

  AC_CHECK_FUNCS([optarg optind opterr optopt \
                  getopt getopt_long getopt_long_only], [],
    [GETOPT_H=getopt.h; AC_LIBOBJ([getopt]) AC_LIBOBJ([getopt1])
     AC_DEFINE([getopt], [rpl_getopt],
       [Define to rpl_getopt if the replacement function should be used])])

  AC_SUBST([GETOPT_H])

Comments (aka things I'm unsure about):

* The intention is to create a new getopt.h when it is needed.  If
  getopt.h doesn't exist on the system, it is created (of course).  If
  the system have getopt.h, but not getopt_long, be conservative and
  assume the system header file might be incorrect as well, and
  provide our own getopt.h.

* I'm abusing AC_CHECK_FUNCS for global variables.  This appears to
  work, but ignores the type of the variables.  If some system ever
  have those symbols, with other types, this part will have to be
  improved.

* 'getopt' is only redefined to 'rpl_getopt' when the system doesn't
  have all of the GNU getopt functions, like getopt_long.  So
  regardless of whether getopt is present or not on the system, as
  long as it doesn't have full GNU getopt, we use rpl_getopt.

* 'getopt_long' etc is NOT redefined.  I didn't see a need; only
  'getopt' can cause a problem, right?

* The variables are wrapped around HAVE_OPTFOO.  Getopt is not
  wrapped, because if we use the file, it will be redefined to
  rpl_getopt.  Likewise getopt_long is not redefined, because no known
  system with getopt_long in libc (i.e. GNU) have problems redefining
  it in the application (?).

* getopt1.c can be cleaned up further, but I didn't want to include
  non-relevant patches now.  Will follow later.

* Someone will have to rename getopt.h to getopt_.h.

It needs more testing.

Native Debian:

checking getopt.h usability... yes
checking getopt.h presence... yes
checking for getopt.h... yes
checking for optarg... yes
checking for optind... yes
checking for opterr... yes
checking for optopt... yes
checking for getopt... yes
checking for getopt_long... yes
checking for getopt_long_only... yes
...
make[3]: Entering directory `/tmp/testdir/lib'
rm -f libfoo.a
ar cru libfoo.a
ranlib libfoo.a
make[3]: Leaving directory `/tmp/testdir/lib'

Cross compiler to uClinux:

checking getopt.h usability... yes
checking getopt.h presence... yes
checking for getopt.h... yes
checking for optarg... yes
checking for optind... yes
checking for opterr... yes
checking for optopt... yes
checking for getopt... yes
checking for getopt_long... no
checking for getopt_long_only... no
...
make[2]: Entering directory `/tmp/testdir/lib'
cp ./getopt_.h getopt.h-t
mv getopt.h-t getopt.h
make  all-am
make[3]: Entering directory `/tmp/testdir/lib'
m68k-uclinux-gcc -DHAVE_CONFIG_H -I. -I. -I..   
-I/usr/local/m68k-uclinux-tools/include  -m5307 -c `test -f 'getopt.c' || echo 
'./'`getopt.c
m68k-uclinux-gcc -DHAVE_CONFIG_H -I. -I. -I..   
-I/usr/local/m68k-uclinux-tools/include  -m5307 -c `test -f 'getopt1.c' || echo 
'./'`getopt1.c
rm -f libfoo.a
ar cru libfoo.a  getopt.o getopt1.o
m68k-uclinux-ranlib libfoo.a
make[3]: Leaving directory `/tmp/testdir/lib'
...
address@hidden:/tmp/testdir$ m68k-uclinux-nm -B lib/libfoo.a
getopt.o: 00000000 t exchange
         U fprintf
         U getenv
00000000 b getopt_data
0000019e t _getopt_initialize
00001042 T _getopt_internal
00000252 T _getopt_internal_r
         U optarg
         U opterr
         U optind
         U optopt
000010b4 T rpl_getopt
         U stderr
         U strchr
         U strcmp
         U strlen
         U strncmp
 
getopt1.o:
         U _getopt_internal
         U _getopt_internal_r
00000000 T getopt_long
00000054 T getopt_long_only
0000007e T _getopt_long_only_r
00000028 T _getopt_long_r
address@hidden:/tmp/testdir$

Index: ChangeLog
===================================================================
RCS file: /cvsroot/gnulib/gnulib/ChangeLog,v
retrieving revision 1.157
diff -u -p -r1.157 ChangeLog
--- ChangeLog   22 Jun 2004 18:28:11 -0000      1.157
+++ ChangeLog   1 Jul 2004 16:09:01 -0000
@@ -1,3 +1,9 @@
+2004-07-01  Simon Josefsson  <address@hidden>
+
+       * modules/getopt (Files): Rename getopt.h to getopt_.h.
+       (Makefile.am): Rewrite, use logic from argz.
+       (Include): Use <getopt.h> instead of "getopt.h".
+
 2004-06-22  Paul Eggert  <address@hidden>
 
        * modules/argz: Omit "#include".
Index: lib/ChangeLog
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/ChangeLog,v
retrieving revision 1.672
diff -u -p -r1.672 ChangeLog
--- lib/ChangeLog       24 Jun 2004 06:05:19 -0000      1.672
+++ lib/ChangeLog       1 Jul 2004 16:09:03 -0000
@@ -1,3 +1,8 @@
+2004-07-01  Simon Josefsson  <address@hidden>
+
+       * getopt.c, getopt1.c: Remove ELIDE_CODE hack.
+       (optarg, optind, opterr, optopt): Wrap in HAVE_OPT???.
+
 2004-06-24  Jim Meyering  <address@hidden>
 
        * obstack.h (obstack_base): Cast to (void *), per documentation.
Index: lib/getopt.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getopt.c,v
retrieving revision 1.42
diff -u -p -r1.42 getopt.c
--- lib/getopt.c        11 Mar 2004 13:04:48 -0000      1.42
+++ lib/getopt.c        1 Jul 2004 16:09:03 -0000
@@ -32,25 +32,6 @@
 
 #include <stdio.h>
 
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-# include <gnu-versions.h>
-# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#  define ELIDE_CODE
-# endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
 /* This needs to come after some library #include
    to get __GNU_LIBRARY__ defined.  */
 #ifdef __GNU_LIBRARY__
@@ -104,7 +85,9 @@
    Also, when `ordering' is RETURN_IN_ORDER,
    each non-option ARGV-element is returned here.  */
 
+#ifndef HAVE_OPTARG
 char *optarg;
+#endif
 
 /* Index in ARGV of the next element to be scanned.
    This is used for communication to and from the caller
@@ -119,18 +102,25 @@ char *optarg;
    how much of ARGV has been scanned so far.  */
 
 /* 1003.2 says this must be 1 before any call.  */
+
+#ifndef HAVE_OPTIND
 int optind = 1;
+#endif
 
 /* Callers store zero here to inhibit the error message
    for unrecognized options.  */
 
+#ifndef HAVE_OPTERR
 int opterr = 1;
+#endif
 
 /* Set to an option character which was unrecognized.
    This must be initialized on some systems to avoid linking in the
    system's own getopt implementation.  */
 
+#ifndef HAVE_OPTOPT
 int optopt = '?';
+#endif
 
 /* Keep a global copy of all internal members of getopt_data.  */
 
@@ -1181,7 +1171,6 @@ getopt (int argc, char *const *argv, con
                           0);
 }
 
-#endif /* Not ELIDE_CODE.  */
 
 #ifdef TEST
 
Index: lib/getopt1.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getopt1.c,v
retrieving revision 1.16
diff -u -p -r1.16 getopt1.c
--- lib/getopt1.c       9 Mar 2004 19:42:23 -0000       1.16
+++ lib/getopt1.c       1 Jul 2004 16:09:03 -0000
@@ -18,7 +18,7 @@
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
 #endif
 
 #ifdef _LIBC
@@ -30,25 +30,6 @@
 
 #include <stdio.h>
 
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
 /* This needs to come after some library #include
    to get __GNU_LIBRARY__ defined.  */
 #ifdef __GNU_LIBRARY__
@@ -96,7 +77,6 @@ _getopt_long_only_r (int argc, char *con
                             1, d);
 }
 
-#endif /* Not ELIDE_CODE.  */
 
 #ifdef TEST
 
Index: m4/ChangeLog
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/ChangeLog,v
retrieving revision 1.560
diff -u -p -r1.560 ChangeLog
--- m4/ChangeLog        22 Jun 2004 18:28:27 -0000      1.560
+++ m4/ChangeLog        1 Jul 2004 16:09:04 -0000
@@ -1,3 +1,7 @@
+2004-07-01  Simon Josefsson  <address@hidden>
+
+       * getopt.m4: Check for getopt, including getopt_long, in system.
+
 2004-06-22  Paul Eggert  <address@hidden>
 
        * argz.m4: New file, which is autoupdated from libtool.
Index: m4/getopt.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/getopt.m4,v
retrieving revision 1.2
diff -u -p -r1.2 getopt.m4
--- m4/getopt.m4        9 Sep 2003 18:36:53 -0000       1.2
+++ m4/getopt.m4        1 Jul 2004 16:09:05 -0000
@@ -1,13 +1,30 @@
-# getopt.m4 serial 2
-dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# getopt.m4 serial 3
+dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
 dnl This file is free software, distributed under the terms of the GNU
 dnl General Public License.  As a special exception to the GNU General
 dnl Public License, this file may be distributed as part of a program
 dnl that contains a configuration script generated by Autoconf, under
 dnl the same distribution terms as the rest of that program.
 
+# The getopt module assume you want GNU getopt, with getopt_long etc,
+# rather than vanilla POSIX getopt.  This means your your code should
+# always include <getopt.h> for the getopt prototypes.
+
 AC_DEFUN([gl_GETOPT],
 [
-  dnl Prerequisites of lib/getopt.c.
-  :
+  gl_PREREQ_GETOPT
+
+  GETOPT_H=
+  AC_CHECK_HEADERS([getopt.h], [], [GETOPT_H=getopt.h])
+
+  AC_CHECK_FUNCS([optarg optind opterr optopt \
+                  getopt getopt_long getopt_long_only], [],
+    [GETOPT_H=getopt.h; AC_LIBOBJ([getopt]) AC_LIBOBJ([getopt1])
+     AC_DEFINE([getopt], [rpl_getopt],
+       [Define to rpl_getopt if the replacement function should be used])])
+
+  AC_SUBST([GETOPT_H])
 ])
+
+# Prerequisites of lib/getopt*.
+AC_DEFUN([gl_PREREQ_GETOPT], [:])
Index: modules/getopt
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/getopt,v
retrieving revision 1.5
diff -u -p -r1.5 getopt
--- modules/getopt      12 Apr 2004 20:12:33 -0000      1.5
+++ modules/getopt      1 Jul 2004 16:09:05 -0000
@@ -2,7 +2,7 @@ Description:
 Process command line arguments.
 
 Files:
-lib/getopt.h
+lib/getopt_.h
 lib/getopt.c
 lib/getopt1.c
 lib/getopt_int.h
@@ -15,10 +15,19 @@ configure.ac:
 gl_GETOPT
 
 Makefile.am:
-lib_SOURCES += getopt.h getopt.c getopt1.c getopt_int.h
+BUILT_SOURCES += $(GETOPT_H)
+EXTRA_DIST += getopt_.h getopt_int.h
+
+# We need the following in order to create an <getopt.h> when the system
+# doesn't have one that works with the given compiler.
+all-local $(lib_OBJECTS): $(GETOPT_H)
+getopt.h: getopt_.h
+       cp $(srcdir)/getopt_.h address@hidden
+       mv address@hidden $@
+MOSTLYCLEANFILES += getopt.h getopt.h-t
 
 Include:
-"getopt.h"
+<getopt.h>
 
 Maintainer:
 all, glibc

reply via email to

[Prev in Thread] Current Thread [Next in Thread]