bug-gnulib
[Top][All Lists]
Advanced

[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)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]