[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gnulib breakage on Tru64 UNIX with commercial C compiler
From: |
Albert Chin |
Subject: |
gnulib breakage on Tru64 UNIX with commercial C compiler |
Date: |
Wed, 4 Apr 2007 21:59:41 -0500 |
User-agent: |
Mutt/1.5.6i |
Tru64 UNIX ships with a C compiler. A commercial version of the
compiler is also available, with extra includes in /usr/include.dtk,
some of which add to the includes in /usr/include. The includes in
/usr/include.dtk include the files in /usr/include with #include_next.
However, because gnulib now creates its own versions of files like
wchar.h and stdlib.h, _only_ the version in /usr/include.dtk is
included, making gnulib break on Tru64 UNIX with the commercial C
compiler.
As an example:
$ ./gnulib-tool --dir=/opt/build/china/gnulib --test \
quotearg allocsa xvasprintf
...
source='../../gllib/xvasprintf.c' object='xvasprintf.o' libtool=no
DEPDIR=.deps depmode=tru64 /bin/ksh ../../build-aux/depcomp cc -DHAVE_CONFIG_H
-I. -I.. -I../../gllib -g -c ../../gllib/xvasprintf.c
cc: Error: ///usr/include.dtk/stdio.h, line 90: Error parsing parameter list.
Found "*" when expecting one of: ",", ")". (notexpecting)
extern int vfscanf(FILE * /*restrict*/ __stream,
------------------------^
The problem is that FILE is not defined. Why? /usr/include.dtk/stdio.h
has:
#ifndef _C99STDIO_H
#define _C99STDIO_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include <standards.h>
#include_next <stdio.h>
...
Unfortunately, "#include_next <stdio.h>" doesn't include
/usr/include/stdio.h. It includes "./stdio.h", the gnulib version of
stdio.h.
Section 2.2.18 of the C++ users manual (probably applicable for C as
well), "Inheritance and Header Files" says the following about
#include_next:
Inheritance means that one object or file derives some of its contents
by virtual copying from another object or file. In the case of C++
header files, for example, one header file includes another and then
replaces or adds something.
If the inheriting header file and the base header file have different
names, inheritance is straightforward: simply write #include "base" in
the inheriting file.
However, if it is necessary to give the inheriting file the same name
as the base file, inheritance is less straightforward.
For example, suppose an application program uses the system header
file sys/signal.h , but the version of /usr/include/sys/signal.h on a
particular system does not do what the program expects. You could
define a local version, perhaps with the name
/usr/local/include/sys/signal.h , to override or add to the one
supplied by the system. Using the -I option for compilation, you could
then write a file sys/signal.h that does what the application program
expects. But if you try to include the standard sys/signal.h in your
version using #include <sys/signal.h> , the result is an infinite
recursion and a fatal compilation error.
Specifying #include </usr/include/sys/signal.h> would include the
correct file, but that technique makes maintenance difficult because
it assumes that the location of the system header files will never
change.
You should therefore use the #include_next directive, which means
"Include the next file with this name." This directive works like
#include but starts searching the list of header file directories
after the directory in which the current file was found.
Suppose you specify -I /usr/local/include , and the list of
directories to search also includes /usr/include . Then suppose that
both directories contain a file named sys/signal.h . Specifying
#include <sys/signal.h> finds your version of the file in the
/usr/local/include directory. If that file contains #include_next
<sys/signal.h> , the search starts after that directory and finds the
correct system standard file in /usr/include .
So, how do we fix this? There is a -nodtk option to the commercial C
compiler which reverts to the system cc but that would need to be done
for _most_ gnulib-using programs, something that is not desirable.
--
albert chin (address@hidden)