This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] dirent.h problem with include_next


James E Wilson wrote:

This turned up while I was trying to get libmudflap to compile for a
mips-elf target.  libmudflap uses dirent.h, and has a configure test for
it.  The configure test worked the first time, i.e. showed that dirent.h
was not supported, but then suddenly started failing after I did an
install, i.e. claimed that dirent.h was supported.

The problem is easy to show with a simple testcase.  I've attached a
typescript showing the problem.  mips-elf does not have dirent.h
support.  I get an error when I try to compile a testcase that uses
dirent.h in the build tree.  But then, after an install, the testcase
works instead of failing, making it look like I have dirent.h support
when I don't.

The problem here is that we are including the build tree dirent.h, which
includes the build tree sys/dirent.h, which does an include_next which
finds the installed dirent.h.  Since dirent.h is protected against
multiple inclusion, the install tree dirent.h does nothing.  So the
testcase works instead of failing as expected.

One way to resolve this problem is to modify sys/dirent.h to undefine
the macro defined in dirent.h.  This way, if we accidentally include the
newlib dirent.h a second time, then we end up with an infinite include
loop.  This is a little gross, but at least we get an error as desired,
and libmudflap configure works as expected.  I've attached a file
showing a trimmed down copy of the result.

An alternative solution here would be to replace the #include_next with
a #error.  If someone does have an alternative dirent.h file, then I see
no reason why we can't force them to install it in the proper place, and
thus avoid the need for the #include_next here.  I note that there is
only one other newlib header that uses #include_next, and that is
limits.h.  However, in this case we are practically guaranteed to find
gcc's version of limits.h, so this does not have the problem of the
dirent.h usage.



I think this idea would be cleaner. The creation of the file was done long ago and it appears the original intention was simply to be a fail-safe:

Thu Oct 21 08:57:24 1993 Ian Lance Taylor (ian@cygnus.com)

       * libc/include/sys/dirent.h: New file.  If it is not overridden by
       a version of libc/sys/*/sys/dirent.h, it includes the next
       <dirent.h> file in case there is one lurking somewhere.

Of the OSes in newlib I know to use dirent.h, all override the file without requiring include_next.

The attached patch has been tested with a full mips-elf toolchain build
and make check. There were no regressions.


------------------------------------------------------------------------

aretha$ cat tmp.c
#include <dirent.h>

int
main (void)
{
return 0;
}
aretha$ cat tmp.script
./xgcc -B./ -B../mips-elf/newlib/ -B../mips-elf/libgloss/mips/ -B../../new-combined/libgloss/mips/ -I../../new-combined/newlib/libc/include tmp.c -Tpmon.ld
aretha$ sh tmp.script
In file included from ../../new-combined/newlib/libc/include/dirent.h:6,
from tmp.c:1:
../../new-combined/newlib/libc/include/sys/dirent.h:16:25: error: dirent.h: No such file or directory
aretha$ cd ..
aretha$ make install >& output
aretha$ cd gcc
aretha$ sh tmp.script
aretha$


------------------------------------------------------------------------


from /home/wilson/COMBINED-TREE/install/lib/gcc/mips-elf/4.1.0/../../../../mips-elf/include/dirent.h:6,
from ../../new-combined/newlib/libc/include/sys/dirent.h:16,
...
from /home/wilson/COMBINED-TREE/install/lib/gcc/mips-elf/4.1.0/../../../../mips-elf/include/dirent.h:6,
from ../../new-combined/newlib/libc/include/sys/dirent.h:16,
from ../../new-combined/newlib/libc/include/dirent.h:6,
from tmp.c:1:
/home/wilson/COMBINED-TREE/install/lib/gcc/mips-elf/4.1.0/../../../../mips-elf/include/dirent.h:6:24: error: #include nested too deeply


------------------------------------------------------------------------

2005-09-29 James E. Wilson <wilson@specifix.com>

* libc/include/sys/dirent.h (_DIRENT_H_): Undef.

Index: dirent.h
===================================================================
RCS file: /services/cvs/cvsroot/gnusense/newlib/newlib/libc/include/sys/dirent.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 dirent.h
*** dirent.h 8 Jul 2004 13:15:34 -0000 1.1.1.1
--- dirent.h 29 Sep 2005 23:23:16 -0000
***************
*** 9,14 ****
--- 9,18 ----
#ifdef __cplusplus
extern "C" {
#endif
+ /* To force an error, we must undef this in case we find a second copy of
+ the main dirent.h file. This can happen if the first copy is in the
+ build tree, and the second copy is in the install tree. */
+ #undef _DIRENT_H_
#include_next <dirent.h>
#ifdef __cplusplus
}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]