This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


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

GCC vs. `make' on Solaris



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


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