automake-history: Dependencies for the User

 
 2.3 Dependencies for the User
 =============================
 
 Description
 -----------
 
 The bugs associated with 'make dist', over time, became a real problem.
 Packages using Automake were being built on a large number of platforms,
 and were becoming increasingly complex.  Broken dependencies were
 distributed in "portable" 'Makefile.in's, leading to user complaints.
 Also, the requirement for 'gcc' and GNU 'make' was a constant source of
 bug reports.  The next implementation of dependency tracking aimed to
 remove these problems.
 
    We realized that the only truly reliable way to automatically track
 dependencies was to do it when the package itself was built.  This meant
 discovering a method portable to any version of make and any compiler.
 Also, we wanted to preserve what we saw as the best point of the second
 implementation: dependency computation as a side effect of compilation.
 
    In the end we found that most modern make implementations support
 some form of include directive.  Also, we wrote a wrapper script that
 let us abstract away differences between dependency tracking methods for
 compilers.  For instance, some compilers cannot generate dependencies as
 a side effect of compilation.  In this case we simply have the script
 run the compiler twice.  Currently our wrapper script ('depcomp') knows
 about twelve different compilers (including a "compiler" that simply
 invokes 'makedepend' and then the real compiler, which is assumed to be
 a standard Unix-like C compiler with no way to do dependency tracking).
 
 Bugs
 ----
 
    * Running a wrapper script for each compilation slows down the build.
    * Many users don't really care about precise dependencies.
    * This implementation, like every other automatic dependency tracking
      scheme in common use today (indeed, every one we've ever heard of),
      suffers from the "duplicated new header" bug.
 
      This bug occurs because dependency tracking tools, such as the
      compiler, only generate dependencies on the successful opening of a
      file, and not on every probe.
 
      Suppose for instance that the compiler searches three directories
      for a given header, and that the header is found in the third
      directory.  If the programmer erroneously adds a header file with
      the same name to the first directory, then a clean rebuild from
      scratch could fail (suppose the new header file is buggy), whereas
      an incremental rebuild will succeed.
 
      What has happened here is that people have a misunderstanding of
      what a dependency is.  Tool writers think a dependency encodes
      information about which files were read by the compiler.  However,
      a dependency must actually encode information about what the
      compiler tried to do.
 
      This problem is not serious in practice.  Programmers typically do
      not use the same name for a header file twice in a given project.
      (At least, not in C or C++.  This problem may be more troublesome
      in Java.)  This problem is easy to fix, by modifying dependency
      generators to record every probe, instead of every successful open.
 
    * Since Automake generates dependencies as a side effect of
      compilation, there is a bootstrapping problem when header files are
      generated by running a program.  The problem is that, the first
      time the build is done, there is no way by default to know that the
      headers are required, so make might try to run a compilation for
      which the headers have not yet been built.
 
      This was also a problem in the previous dependency tracking
      implementation.
 
      The current fix is to use 'BUILT_SOURCES' to list built headers
      (⇒Sources (automake)Sources.).  This causes them to be built
      before any other build rules are run.  This is unsatisfactory as a
      general solution, however in practice it seems sufficient for most
      actual programs.
 
    This code is used since Automake 1.5.
 
    In GCC 3.0, we managed to convince the maintainers to add special
 command-line options to help Automake more efficiently do its job.  We
 hoped this would let us avoid the use of a wrapper script when
 Automake's automatic dependency tracking was used with 'gcc'.
 
    Unfortunately, this code doesn't quite do what we want.  In
 particular, it removes the dependency file if the compilation fails;
 we'd prefer that it instead only touch the file in any way if the
 compilation succeeds.
 
    Nevertheless, since Automake 1.7, when a recent 'gcc' is detected at
 'configure' time, we inline the dependency-generation code and do not
 use the 'depcomp' wrapper script.  This makes compilations faster for
 those using this compiler (probably our primary user base).  The
 counterpart is that because we have to encode two compilation rules in
 'Makefile' (with or without 'depcomp'), the produced 'Makefile's are
 larger.