Additionally, there's a problem on mingw, when using --enable-shared: The value of 'optind' that the main() program sees is always 1.
This patch fixes it. 2025-06-29 Bruno Haible <br...@clisp.org> options: Support use in a shared library on mingw. * lib/options.h (_gl_get_next_option): New declaration. (get_next_option): On mingw, define in terms of _gl_get_next_option. * lib/options.c (_gl_get_next_option): On mingw, define this function instead of get_next_option. diff --git a/lib/options.c b/lib/options.c index f981613bf8..6ff6064698 100644 --- a/lib/options.c +++ b/lib/options.c @@ -121,7 +121,11 @@ _gl_start_options (int argc, char **argv, } int +#ifdef __MINGW32__ +_gl_get_next_option (int *optind_p, char **optarg_p, int *optopt_p) +#else get_next_option (void) +#endif { if (state.argv == NULL) { @@ -141,5 +145,19 @@ get_next_option (void) *(options[i].variable) = options[i].value; } } +#ifdef __MINGW32__ + /* On mingw, when this file is compiled into a shared library, it pulls + mingw's getopt.o file (that defines getopt_long, opterr, optind, optarg, + optopt) into the same shared library. Since these variables are declared + and defined without any __declspec(dllexport) or __declspec(dllimport), + the effect is that there are two copies of the variables: one in the + shared library and one in the executable. Upon return from this function, + we need to copy the values of the output variables (optind, optarg, optopt) + from the shared library into the executable, where the main() function will + pick them up. */ + *optind_p = optind; + *optarg_p = optarg; + *optopt_p = optopt; +#endif return ret; } diff --git a/lib/options.h b/lib/options.h index 044cc73265..66d8710ca4 100644 --- a/lib/options.h +++ b/lib/options.h @@ -247,6 +247,10 @@ extern void _gl_start_options (int argc, /*const*/ char **argv, specified) ':'. If the processing is terminated, it returns -1. */ extern int get_next_option (void); +#ifdef __MINGW32__ +extern int _gl_get_next_option (int *optind_p, char **optarg_p, int *optopt_p); +# define get_next_option() _gl_get_next_option (&optind, &optarg, &optopt) +#endif #ifdef __cplusplus }