[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 *));
- getopt link error on MSVC,
Bruno Haible <=