Discussion:
Build error due to missing locale_t on IBM z/OS
Daniel Richard G.
2017-10-08 07:05:36 UTC
Permalink
Hello list,

I tested the latest tree on z/OS, and encountered this compile error:

$ make check
make check-recursive
make[1]: Entering directory `/tmp/gnulib-build/gllib'
make[2]: Entering directory `/tmp/gnulib-build/gllib'
source='/tmp/testdir/gllib/hard-locale.c' object='hard-locale.o' libtool=no \
DEPDIR=.deps depmode=aix /bin/sh /tmp/testdir/build-aux/depcomp \
xlc-wrap -DHAVE_CONFIG_H -I. -I/tmp/testdir/gllib -I.. -DGNULIB_STRICT_CHECKING=1 -D_XOPEN_SOURCE=600 -DNSIG=39 -qhaltonmsg=CCN3296 -g -qfloat=ieee -qlanglvl=extc99 -c -o hard-locale.o /tmp/testdir/gllib/hard-locale.c
ERROR CCN3166 ./locale.h:648 Definition of function locale_t requires parentheses.
ERROR CCN3276 ./locale.h:648 Syntax error: possible missing '{'?
ERROR CCN3273 /usr/include/stdlib.h:64 Missing type in declaration of div_t.
ERROR CCN3166 /usr/include/stdlib.h:544 Definition of function div_t requires parentheses.
[...]

This system has a fairly minimal locale.h; there is no locale_t type,
and while duplocale() is detected in a link test, the additional
check fails:

configure:11007: checking for duplocale
configure:11007: xlc-wrap -o conftest -g -qfloat=ieee -qlanglvl=extc99 -D_XOPEN_SOURCE=600 -DNSIG=39 -qhaltonmsg=CCN3296 conftest.c >&5
configure:11007: $? = 0
configure:11007: result: yes
[...]
configure:37582: checking whether duplocale(LC_GLOBAL_LOCALE) works
configure:37672: xlc-wrap -o conftest -g -qfloat=ieee -qlanglvl=extc99 -D_XOPEN_SOURCE=600 -DNSIG=39 -qhaltonmsg=CCN3296 conftest.c >&5
ERROR CCN3275 ./conftest.c:453 Unexpected text loc encountered.
ERROR CCN3045 ./conftest.c:453 Undeclared identifier locale_t.
ERROR CCN3045 ./conftest.c:463 Undeclared identifier LC_GLOBAL_LOCALE.
ERROR CCN3045 ./conftest.c:463 Undeclared identifier loc.
CCN0793(I) Compilation failed for file ./conftest.c. Object file not created.
configure:37672: $? = 12

I don't see duplocale() anywhere under /usr/include/, so the link test
result is probably spurious.


--Daniel


(Please Cc: any replies to me, as I am not subscribed to this list)
--
Daniel Richard G. || ***@iSKUNK.ORG
My ASCII-art .sig got a bad case of Times New Roman.
Bruno Haible
2017-10-08 08:53:21 UTC
Permalink
Hi Daniel,
Since you are the only one here on this list who has access to z/OS, we need
more details in order to perform the analysis:

1) What is 'xlc-wrap', compared to 'xlc'? (I'd like to know if something is
missing in Autoconf or gnulib-common.m4.)

2)
Post by Daniel Richard G.
ERROR CCN3166 ./locale.h:648 Definition of function locale_t requires parentheses.
ERROR CCN3276 ./locale.h:648 Syntax error: possible missing '{'?
Can you show the lines around 648 in the generated locale.h? Unfortunately the
line numbers in locale.h and locale.in.h are not the same.

3)
Post by Daniel Richard G.
ERROR CCN3273 /usr/include/stdlib.h:64 Missing type in declaration of div_t.
ERROR CCN3166 /usr/include/stdlib.h:544 Definition of function div_t requires parentheses.
Can you show the lines around 64 and 544 in /usr/include/stdlib.h?

Bruno
Daniel Richard G.
2017-10-08 22:17:49 UTC
Permalink
Hi Bruno,
Post by Bruno Haible
Hi Daniel,
Since you are the only one here on this list who has access to z/OS,
1) What is 'xlc-wrap', compared to 'xlc'? (I'd like to know if
something is missing in Autoconf or gnulib-common.m4.)
xlc-wrap is my own script. It is quite simple:

#!/bin/sh
exec xlc -qnosearch "$@" -qsearch=/usr/include

It is used to work around a non-standard behavior of the compiler, where
/usr/include/ is effectively first in the header search path (before any
-I directories). Obviously an issue for Gnulib's replacement headers.

I haven't gotten around yet to submitting this issue formally to Gnulib.
For an example of how such a workaround can be integrated, look at
AC_ZOS_USS in m4/arch.m4 in the GNU Gawk source. It's fairly
comprehensive in addressing the toolchain weirdness of z/OS.
Post by Bruno Haible
2)
Post by Daniel Richard G.
ERROR CCN3166 ./locale.h:648 Definition of function locale_t requires parentheses.
ERROR CCN3276 ./locale.h:648 Syntax error: possible missing '{'?
Can you show the lines around 648 in the generated locale.h?
Unfortunately the line numbers in locale.h and locale.in.h are not
the same.
Line 648 is marked below:

-----begin locale.h excerpt-----
#if 1
# if 1
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef duplocale
# define duplocale rpl_duplocale
# endif
_GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1))); <---HERE
_GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale));
# else
# if 1
_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale));
# endif
# endif
# if 1
_GL_CXXALIASWARN (duplocale);
-----end locale.h excerpt-----

When I looked at the preprocessed source, the first mention of locale_t
came from that line. So it seems that while all other systems provide
locale_t, z/OS is an exception.
Post by Bruno Haible
3)
Post by Daniel Richard G.
ERROR CCN3273 /usr/include/stdlib.h:64 Missing type in declaration of div_t.
ERROR CCN3166 /usr/include/stdlib.h:544 Definition of function div_t requires parentheses.
Can you show the lines around 64 and 544 in /usr/include/stdlib.h?
Sure...

-----begin stdlib.h excerpt-----
#if __TARGET_LIB__ >= __EDC_LE
typedef struct __div_t
#else
typedef struct div_t
#endif
{
int quot; /* quotient of integer division */
int rem; /* remainder of integer division */
} div_t; <---HERE
[...]
int wctomb ();
size_t mbstowcs ();
size_t wcstombs ();
#else
div_t div (int, int); <---HERE
long int labs (long int);
ldiv_t ldiv (long int, long int);
-----end stdlib.h excerpt-----

These errors are probably cascaded from the earlier syntax error, so I
wouldn't worry about them for now.


--Daniel
--
Daniel Richard G. || ***@iSKUNK.ORG
My ASCII-art .sig got a bad case of Times New Roman.
Bruno Haible
2017-10-09 16:11:48 UTC
Permalink
Hi Daniel,
Post by Daniel Richard G.
Post by Bruno Haible
1) What is 'xlc-wrap', compared to 'xlc'? (I'd like to know if
something is missing in Autoconf or gnulib-common.m4.)
#!/bin/sh
It is used to work around a non-standard behavior of the compiler, where
/usr/include/ is effectively first in the header search path (before any
-I directories). Obviously an issue for Gnulib's replacement headers.
I haven't gotten around yet to submitting this issue formally to Gnulib.
For an example of how such a workaround can be integrated, look at
AC_ZOS_USS in m4/arch.m4 in the GNU Gawk source.
Thanks, I understand. However, I don't think it is adequate to put this into
a specific package (gawk) or gnulib; rather, I like the way Autoconf-generated
configure files obey the environment variables.
For even difficult cases (msvc builds on Windows) this approach is sufficient:
Autoconf/Automake maintains a 'compile' script (that the user can modify locally
if needed); the user sets an environment variable (CC) to point to this script.
This way
- the same recipe works for most GNU packages,
- individual GNU package maintainers don't need to change their build system,
- the wrapper script can be maintained in a central place.

The user then only needs to have a specific set of environment variables for
each machine. Like this (for AIX):
CC="xlc -q64"; CXX="xlC -q64"; AR="ar -X 64"; NM="nm -X 64"; export CC CXX AR NM
or this (for native Windows):
CC="$HOME/msvc/compile cl -nologo"; export CC
CFLAGS="-MD"; export CFLAGS
CXX="$HOME/msvc/compile cl -nologo"; export CXX
CXXFLAGS="-MD"; export CXXFLAGS
CPPFLAGS="-D_WIN32_WINNT=$win32_target -I/usr/local/msvc64/include"; export CPPFLAGS
LDFLAGS="-L/usr/local/msvc64/lib"; export LDFLAGS
LD="link"; export LD
NM="dumpbin -symbols"; export NM
STRIP=":"; export STRIP
AR="$HOME/msvc/ar-lib lib"; export AR
RANLIB=":"; export RANLIB
Post by Daniel Richard G.
Post by Bruno Haible
2)
Post by Daniel Richard G.
ERROR CCN3166 ./locale.h:648 Definition of function locale_t requires parentheses.
ERROR CCN3276 ./locale.h:648 Syntax error: possible missing '{'?
Can you show the lines around 648 in the generated locale.h?
Unfortunately the line numbers in locale.h and locale.in.h are not
the same.
-----begin locale.h excerpt-----
#if 1
# if 1
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef duplocale
# define duplocale rpl_duplocale
# endif
_GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1))); <---HERE
_GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale));
# else
# if 1
_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale));
# endif
# endif
# if 1
_GL_CXXALIASWARN (duplocale);
-----end locale.h excerpt-----
When I looked at the preprocessed source, the first mention of locale_t
came from that line. So it seems that while all other systems provide
locale_t, z/OS is an exception.
But the autoconfiguration found that HAVE_DUPLOCALE=1 and REPLACE_DUPLOCALE=1.
So, there must be a duplocale function somewhere. Is it declared somewhere, and
if yes, what is its prototype?
Post by Daniel Richard G.
Post by Bruno Haible
3)
Post by Daniel Richard G.
ERROR CCN3273 /usr/include/stdlib.h:64 Missing type in declaration of div_t.
ERROR CCN3166 /usr/include/stdlib.h:544 Definition of function div_t requires parentheses.
Can you show the lines around 64 and 544 in /usr/include/stdlib.h?
These errors are probably cascaded from the earlier syntax error, so I
wouldn't worry about them for now.
OK.

Bruno
Daniel Richard G.
2017-10-09 19:11:21 UTC
Permalink
Post by Bruno Haible
Thanks, I understand. However, I don't think it is adequate to put
this into a specific package (gawk) or gnulib; rather, I like the way
Autoconf-generated configure files obey the environment variables.
Environment variables are still respected in the Gawk framework. Gawk is
somewhat of an oddball anyway, being such a base-level dependency for
other parts of the GNU system. But other packages should eventually be
able to gain similar logic "for free."
Post by Bruno Haible
For even difficult cases (msvc builds on Windows) this approach is
sufficient: Autoconf/Automake maintains a 'compile' script (that the
user can modify locally if needed); the user sets an environment
variable (CC) to point to this script.
This way
- the same recipe works for most GNU packages,
- individual GNU package maintainers don't need to change their build system,
- the wrapper script can be maintained in a central place.
The "compile" script appears to be narrowly aimed at compilers that
don't understand "-c -o", however. If it could be broadened from that,
then yes, this would be a good place to put the XLC logic.
Post by Bruno Haible
The user then only needs to have a specific set of environment
[...]

That all still works, with the exception of some z/OS compilers (c89)
that require options to be passed in the _C89_OPTIONS environment
variable due to quoting issues.
Post by Bruno Haible
But the autoconfiguration found that HAVE_DUPLOCALE=1 and
REPLACE_DUPLOCALE=1. So, there must be a duplocale function somewhere.
Is it declared somewhere, and if yes, what is its prototype?
No prototype for duplocale() exists in the system headers. There is
a symbol for it present in the C library, and the configure check
picks this up. But if you attempt to call the function, you get a
runtime error:

cat duplocale-test.c
#include <locale.h>
int main(void)
{
return duplocale(NULL);
}

$ xlc -o duplocale-test duplocale-test.c

$ ./duplocale-test
CEE3728S The use of a function, which is not supported by this release of Language Environment was detected.
From entry point main at compile unit offset +0000005E at entry offset +0000005E at address 1CE0A986.
Killed

My impression is that a stub was added to facilitate porting, but you're
not supposed to actually use it. (Locale support on z/OS is quite
limited anyway.)


--Daniel
--
Daniel Richard G. || ***@iSKUNK.ORG
My ASCII-art .sig got a bad case of Times New Roman.
Loading...