---THE PROBLEM---
I encountered an error building libxml2, in the course of a konstruct
build:
...
gcc -DHAVE_CONFIG_H -I. -I. -I. -I./include -I./include -D_REENTRANT -O3 ...
nanohttp.c: In function `xmlNanoHTTPScanAnswer':
nanohttp.c:785: warning: cast discards qualifiers from pointer target type
nanohttp.c:811: warning: cast discards qualifiers from pointer target type
nanohttp.c:836: warning: cast discards qualifiers from pointer target type
nanohttp.c:842: warning: cast discards qualifiers from pointer target type
nanohttp.c:848: warning: cast discards qualifiers from pointer target type
nanohttp.c:854: warning: cast discards qualifiers from pointer target type
nanohttp.c: In function `xmlNanoHTTPConnectAttempt':
nanohttp.c:973: error: `len' undeclared (first use in this function)
nanohttp.c:973: error: (Each undeclared identifier is reported only once
nanohttp.c:973: error: for each function it appears in.)
make[2]: *** [nanohttp.lo] Error 1
Line 973 was a local variable declaration of type SOCKLEN_T:
...
if ( FD_ISSET(s, &wfd) ) {
--> SOCKLEN_T len;
len = sizeof(status);
#ifdef SO_ERROR
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) {
/* Solaris error code */
__xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
...
SOCKLEN_T, as given in config.h, had an empty definition:
...
/* #undef HAVE_LIBHISTORY */
/* #undef HAVE_LIBREADLINE */
#define SOCKLEN_T
#define HAVE_LIBPTHREAD
#define HAVE_PTHREAD_H
...
So I guessed that something had gone wrong with a configure-script test. A
relevant excerpt from config.log:
...
configure:25621: checking for type of socket length (socklen_t)
configure:25641: gcc -c -O3 -pipe -march=athlon-tbird -mmmx -m3dnow ...
configure:25635: warning: function declaration isn't a prototype
configure: failed program was:
#line 25630 "configure"
#include "confdefs.h"
#include <stddef.h>
#include <sys/types.h>
#include <sys/socket.h>
int main() {
(void)getsockopt (1, 1, 1, NULL, (socklen_t *)NULL)
; return 0; }
...
(The configure script went on to try "size_t *" and "int *", to no better
effect. Result: "could not determine.")
This had me scratching my head for a while. GCC gave nothing more than a
warning; why did this test fail? I could even compile the test program
manually, and confirm that GCC was returning 0.
---THE ANSWER---
The socklen_t test compile is performed using the custom AC_TRY_COMPILE2
macro (instead of the standard AC_TRY_COMPILE); this macro signals failure
not only if the compile fails, but also if the compiler produces any
terminal output whatsoever. The idea is that a mismatched type on the fifth
argument of getsockopt() will produce a compiler warning---which in this
case correctly indicates a failure of the test---whereas the correct type
will compile without any warnings at all.
UNLESS, of course, something else in the test program produces a warning...
which will then cause all variations of the fifth argument type to fail.
Something like the non-prototypical main() declaration, perhaps? That would
not pose a problem for most people, since GCC doesn't print warnings for
non-prototype declarations by default. I set CFLAGS in my .bashrc,
however---and I keep a scary-looking set of -Wxxx flags in it.
---THE SOLUTION---
A one-line patch is attached, against acinclude.m4. It will change the "int
main()" declaration in the test program body to "int main(void)"; this much
solves the problem on my end.
Beyond that, I would suggest tweaking the socklen_t test clause in
configure.in to bomb out with an AC_MSG_ERROR instead of an AC_MSG_WARN if
it can't determine a value for SOCKLEN_T. It should not be possible for
the configure script to produce a config.h file as previously described.
(Maybe it could fall back to "#define SOCKLEN_T int", etc.---anything so
long as it doesn't leave the code in an uncompilable state.)
And even further... I came across this message/thread in the mailing list
archive, from nearly three years ago:
http://mail.gnome.org/archives/xml/2001-August/msg00061.html
I would agree that the socklen_t test code is icky, but more so than that,
I would say it is rather fragile for what it's trying to do. Can one really
be sure that a given snippet of code will compile with no warnings at all?
Or heck, what about vendor compilers that print out a "Evaluation version:
please contact Yoyodyne Inc. for a permanent license" header on every
invocation? The possibilities are endless....
So far as I've seen, the approach Albert Chin was proposing---having the
compiler check for a prototype mismatch---is Autoconf's usual MO. I can
understand not wanting to fix what's not broken, but the test as currently
written feels like a shoe waiting to drop. I'm surprised that relatively
few people seem to have had a problem with it.
Anyway, I hope this has been of some usefulness. Please Cc: any replies to
me, as I am not subscribed to this list.
Regards,
--Danny
--
NAME = Daniel Richard G. ## Remember, skunks _\|/_ meef?
EMAIL1 = skunk iskunk org ## don't smell bad--- (/o|o\) /
EMAIL2 = skunk alum mit edu ## it's the people who < (^),>
WWW = http://www.******.org/ ## annoy them that do! / \
--
(****** = site not yet online)
Attachment:
fix-socklen_t-test.patch
Description: Text document