bug-gnulib
[Top][All Lists]
Advanced

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

getopt link error on MSVC


From: Bruno Haible
Subject: getopt link error on MSVC
Date: Sun, 18 Dec 2016 13:09:28 +0100
User-agent: KMail/4.8.5 (Linux/3.8.0-44-generic; KDE/4.8.5; x86_64; ; )

I see the following test link failure on MSVC, from a use of the 'getopt-posix'
module:

/home/bruno/msvc/compile cl -nologo -DHAVE_CONFIG_H -DEXEEXT=\".exe\" -I. 
-I../../gltests -I..  -DGNULIB_STRICT_CHECKING=1 -DIN_GNULIB_TESTS=1 -I. 
-I../../gltests -I.. -I../../gltests/.. -I../gllib -I../../gltests/../gllib 
-D_WIN32_WINNT=_WIN32_WINNT_WINXP -I/usr/local/msvc32/include  -MD -c -o 
test-getopt.obj `cygpath -w '../../gltests/test-getopt.c'`
test-getopt.c
/home/bruno/msvc/compile cl -nologo  -MD  -L/usr/local/msvc32/lib -o 
test-getopt.exe test-getopt.obj libtests.a ../gllib/libgnu.a libtests.a   
test-getopt.obj : error LNK2001: unresolved external symbol _getopt
test-getopt.obj : error LNK2019: unresolved external symbol _optarg referenced 
in function _getopt_loop
test-getopt.obj : error LNK2019: unresolved external symbol _optind referenced 
in function _test_getopt
test-getopt.obj : error LNK2019: unresolved external symbol _opterr referenced 
in function _test_getopt
test-getopt.obj : error LNK2019: unresolved external symbol _optopt referenced 
in function _getopt_loop
test-getopt.exe : fatal error LNK1120: 5 unresolved externals
make[4]: *** [Makefile:6287: test-getopt.exe] Error 2

This compilation error goes away if test-getopt.c is changed to include
<getopt.h> instead of <unistd.h>. Nevertheless, it should also work with
<unistd.h>, since that's the header according to POSIX and the glibc doc:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html
https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html

Currently, the compiled getopt.obj defines the symbols 'rpl_getopt', 
'rpl_optarg'
etc. But when #include <unistd.h> is used, the compiled test-getopt.obj
requests the symbols 'getopt', 'optarg', etc.

This fixes it. Reminder for the reviewer:
- "#if defined __GETOPT_PREFIX" is true if this code in used in gnulib, whereas
  it's false inside glibc.
- "#if defined __need_getopt" is true if this code is being included from 
<unistd.h>.
  <unistd.h> wants only the declarations mentioned in
  http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html


2016-12-18  Bruno Haible  <address@hidden>

        getopt: Fix link error for users of getopt() in <unistd.h>.
        * lib/getopt.in.h (getopt etc.): Do the macro definitions also when
        __need_getopt is defined. Undefine all macros before defining them.
        * modules/getopt (Include): Clarify that including <unistd.h> is also
        OK.
        * tests/test-getopt.c: Add comment.

diff --git a/lib/getopt.in.h b/lib/getopt.in.h
index 0f72182..64469b7 100644
--- a/lib/getopt.in.h
+++ b/lib/getopt.in.h
@@ -47,15 +47,20 @@
    identifiers so that they do not collide with the system functions
    and variables.  Renaming avoids problems with some compilers and
    linkers.  */
-#if defined __GETOPT_PREFIX && !defined __need_getopt
-# if address@hidden@
-#  define __need_system_stdlib_h
-#  include <stdlib.h>
-#  undef __need_system_stdlib_h
-#  include <stdio.h>
-#  include <unistd.h>
+#if defined __GETOPT_PREFIX
+# if !defined __need_getopt
+#  if address@hidden@
+#   define __need_system_stdlib_h
+#   include <stdlib.h>
+#   undef __need_system_stdlib_h
+#   include <stdio.h>
+#   include <unistd.h>
+#  endif
+#  undef __need_getopt
 # endif
-# undef __need_getopt
+# undef __GETOPT_CONCAT
+# undef __GETOPT_XCONCAT
+# undef __GETOPT_ID
 # undef getopt
 # undef getopt_long
 # undef getopt_long_only
@@ -64,6 +69,7 @@
 # undef optind
 # undef optopt
 # undef option
+# undef _getopt_internal
 # define __GETOPT_CONCAT(x, y) x ## y
 # define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
 # define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
diff --git a/modules/getopt b/modules/getopt
index 5d4f3c4..53c844d 100644
--- a/modules/getopt
+++ b/modules/getopt
@@ -17,7 +17,7 @@ configure.ac:
 Makefile.am:
 
 Include:
-<getopt.h>
+<getopt.h> or <unistd.h>
 
 License:
 LGPL
diff --git a/tests/test-getopt.c b/tests/test-getopt.c
index 505cb2a..04e1ae6 100644
--- a/tests/test-getopt.c
+++ b/tests/test-getopt.c
@@ -38,7 +38,17 @@ SIGNATURE_CHECK (getopt_long_only, int, (int, char 
*__getopt_argv_const *,
 
 #endif
 
-#include <unistd.h>
+/* POSIX and glibc provide the getopt() function in <unistd.h>, see
+   http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html
+   https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html
+   But gnulib provides the getopt() function in <getopt.h>, not in <unistd.h>.
+   Nevertheless the getopt() function should also be found in <unistd.h>.
+   We can test it either way.  */
+#if 0
+# include <getopt.h>
+#else
+# include <unistd.h>
+#endif
 
 #include "signature.h"
 SIGNATURE_CHECK (getopt, int, (int, char * const[], char const *));




reply via email to

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