This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
GCC vs. `make' on Solaris
- To: gcc at gcc dot gnu dot org
- Subject: GCC vs. `make' on Solaris
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Fri, 11 May 2001 14:01:21 -0700
- Organization: CodeSourcery, LLC
Right now, GCC won't bootstrap correctly on Solaris. I've tracked the
problem down to interactions between `make', `touch', Solaris, and
NFS.
The background is this:
- Solaris 2.8 supports sub-second time-stamps on files. In addition
to the traditional "seconds since 1970" field, there is an
additional field that indicates the number of nanoseconds.
- GNU Make 3.79.1 (and possibly earlier versions) process the
complete timestamp by default. (There's a configury option
to turn off this behavior, but the default is to use the
full timestamp.) Solaris make also checks these values.
- Solaris 2.8 has a bug in its implementation of the `utime'
system-call.
In particular, when you call `utime (path, NULL)' to set the
timestamp of PATH to the current-time, the nanoseconds are
set correctly on an NFS-mounted file system, mounted on another
Solaris machine, but are always set to zero on a local disk.
- `touch' uses `utime' to set the timestamp on a file.
Don't believe me? I've got a program that prints out the two
timestamps, called `print-time'. Here's a little session:
nunki[268]% rm -f foo
nunki[269]% touch foo
nunki[270]% print-time foo
989612157 0
nunki[271]% rm -f ~/foo
nunki[272]% touch ~/foo
nunki[273]% print-time ~/foo
989612178 771935000
Of course, I could get a `0' there by incredibly random chance -- but
it's very repeatable.
This is a problem because GCC's Makefiles have rules like:
s-foo: bar
bar > tmp-baz
move-if-change tmp-baz baz
touch s-foo
The assumption is that by the end of this, we'll have an s-foo stamp
file that has a timestamp at least as late as the timestamps on baz
and bar. But, that's false because s-foo gets a zero in the
nanosecond field, but baz does not because an ordinary `creat' call
does the right thing.
The reason this problem is critical is that a `make bootstrap' results
in parts of cc1 being rebuilt after the bootstrap, and during the
library build. This time, the build occurs with the system compiler.
In other words, the compiler that you end up with isn't really
bootstrapped -- its bootstrapped and then has some stage1 modules
mixed back in. In addition, some things break because pieces of the
code that aren't recompiled and checked for particular GCC versions
with #if end up being incompatible with pieces there were recompiled.
Badness everywhere.
There are a lot of possible solutions:
1. Use `echo' or `cat' in place of `touch' to avoid the bug.
In other words, use:
rm -f s-foo && echo > s-foo
This works because `creat' works; it's just `utime' that's
broken.
2. Get rid of all this use of stamp files.
There's really not a whole lot of point. If the stamp
file is out of date, everything that depends on it will
be rebuilt anyhow -- even if move-if-change decides that
nothing really changed. And this crud makes for a ton
of complexity in the Makefiles.
There are a few places where the stamp files really are
necessary, but there aren't very many. In those cases,
we could use the workaround above.
I am favoring this solution.
3. Wire `make bootstrap' to not remake in the GCC subdirectory.
That will make `make bootstrap' work again -- but does nothing
to fix the realy underlying problem. For example, a
`make' after `make bootstrap' will still cause lots of rebuilds.
Object soon if you want this stamp-file stuff to stick around.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com