Eli Zaretskii wrote:
> Here is where things become interesting. 'text' is the value of
> 'optarg' which is supposed to be set by getopt_long:
>
> case CONF_DIR_OPT:
> push_include_directory (&conf_dirs, optarg);
> break;
>
> And optarg is NULL:
>
> (gdb) p optarg
> $7 = 0x0
>
> I don't fully understand why optarg is NULL. The actual name of the
> variable is rpl_optarg, because config.h does:
>
> /* Define to rpl_ if the getopt replacement functions and variables should
> be
> used. */
> #define __GETOPT_PREFIX rpl_
>
> But for some reason, rpl_optarg in texi2any.c and in getopt.c resolve
> to two different addresses. Here's what I see while stepping through
> the code:
>
> 1320 option_character = getopt_long (argc, argv,
> "VhvFc:D:e:f:I:P:o:E:U:",
> (gdb) s
> rpl_getopt_long (argc=31, argv=0x1043208,
> options=0xd5e8b6 <format_names+1206> "VhvFc:D:e:f:I:P:o:E:U:",
> long_options=0xd5d200 <long_options>, opt_index=0x5ffc38) at
> getopt1.c:31
> 31 return _getopt_internal (argc, (char **) argv, options,
> long_options,
> (gdb) s
> rpl_getopt_internal (argc=31, argv=0x1043208,
> optstring=0xd5e8b6 <format_names+1206> "VhvFc:D:e:f:I:P:o:E:U:",
> longopts=0xd5d200 <long_options>, longind=0x5ffc38, long_only=0,
> posixly_correct=0) at getopt.c:710
> 710 getopt_data.optind = optind;
> (gdb) n
> 711 getopt_data.opterr = opterr;
> (gdb) n
> 713 int result = _getopt_internal_r (argc, argv, optstring, longopts,
> (gdb) n
> 717 optind = getopt_data.optind;
> (gdb) n
> 718 optarg = getopt_data.optarg;
> (gdb) n
> 719 optopt = getopt_data.optopt;
> (gdb) p optarg
> $4 = 0x10429d8 "./../perl/t/init/"
> (gdb) p rpl_optarg
> $5 = 0x10429d8 "./../perl/t/init/"
> (gdb) info address rpl_optarg
> Symbol "rpl_optarg" is static storage at address 0x77676af8.
> (gdb) n
> 721 return result;
> (gdb) n
> 722 }
> (gdb) n
> rpl_getopt_long (argc=31, argv=0x1043208,
> options=0xd5e8b6 <format_names+1206> "VhvFc:D:e:f:I:P:o:E:U:",
> long_options=0xd5d200 <long_options>, opt_index=0x5ffc38) at
> getopt1.c:33
> 33 }
> (gdb) p rpl_optarg
> $6 = 0x10429d8 "./../perl/t/init/"
> (gdb) n
> main (argc=31, argv=0x1043208, env=0x1041808) at texi2any.c:1324
> 1324 if (option_character == -1)
> (gdb) p rpl_optarg
> $7 = 0x0
> (gdb) info address rpl_optarg
> Symbol "rpl_optarg" is static storage at address 0xd63114.
>
> Note how optarg was computed correctly inside getopt.c, but "lost" its
> value when control flow returned to the main function. Also note that
> GDB shows two different addresses for rpl_optarg in these two modules.
> I presume this latter fact is the reason why I get NULL in main, but I
> don't understand what snafu caused that. Perhaps Bruno (CC'ed) could
> suggest where to look.
Suggestion 1:
In which EXE or DLL is each located? The one in main surely is in
ctexi2any.exe. Where does the other one, referenced by rpl_getopt_long,
reside? I.e. is rpl_getopt_long compiled into the executable or some DLL?
If it is compiled into a DLL, the declaration of 'optarg' needs to be
changed from
char *optarg;
to
LIBFOO_DLL_VARIABLE char *optarg;
where LIBFOO_DLL_VARIABLE needs to expand to
__declspec(dllexport)
or
__declspec(dllimport)
depending on the compilation unit.
This is the approach chosen by GNU gettext, which has a copy of
rpl_getopt_long in its libgettextlib DLL. It uses a local modification
of the Gnulib 'getopt' module:
https://gitweb.git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=gnulib-local/lib/getopt-core.h.diff;h=5e385cf7d32f66cad47d11785038441539521505;hb=HEAD
Suggestion 2:
What other options are contained in perl_conf_CFLAGS and perl_conf_LDFLAGS?
Suggestion 3 (from ChatGPT):
Are some compilation units compiled with /MT and others with /MD ?
> But then this Gnulib
> trick with renaming was explicitly meant to avoid messing with the
> system's getopt, so I'd expect that to work in my case.
Yes, rpl_optarg is intentionally meant to be different from the mingw
optarg.
Bruno