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 <br...@clisp.org> 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 !@HAVE_GETOPT_H@ -# 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 !@HAVE_GETOPT_H@ +# 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 *));