5 ms·
GCC actually gets it wrong, as does almost every compiler and makefile combination. Consider this realistic example. Realistic in that I've encountered it in
by jlokier 6y ago
GCC actually gets it wrong, as does almost every compiler and makefile combination.
Consider this realistic example. Realistic in that I've encountered it in the real world and seen buggy demos shipped because of it, with non-reproducible bugs.
We have a search path for headers, like so:
-Imyinc -I../dep1/inc -Idep2/inc -I/usr/include
We compile a source file which contains:
#include "creative.h"
GCC outputs a dependency which is read into the Makefile next time:
object.o: ../dep2/inc/creative.h
Looks good! Later that day we update from our upstream dependencies:
git pull
Which adds a file ../dep1/inc/creative.h
Recompiling, the project works:
make
...
make test
=> 144,123 pass, 0 fail - well done, you earned a coffee!
We captured automatic dependencies, this should be good to ship.
But no:
make clean
...
make
...
make test
=> FAIL!
What happened? Turns out someone upstream moved (by copying) creative.h to ../dep1/inc and forgot to remove the old copy in ../dep2/inc. Then someone edited a data structure in that file. Automatic dependencies gave everyone false confidence in the build results seen by different people.
That kind of automatic dependency is insufficient because it doesn't capture "negative file results" during path searches, where output depends on a file not existing, and changes if a new file is created.
It is possible to use Makefiles with this handled accurately in the automatic dependency tracking, but I haven't seen it done often.
An equivalent problem occurs in caches which automatically track data dependencies used to generate results. For example web pages generated from a combination of files, templates and data, build artifacts such as container/VM images, or at a much lower level, data dependencies inside calculations with conditional branches. To do caching right, they must validate negative tests as well as positive that arise in searches. I've seen a surprising number of cache implementations which don't try particularly hard to get this right.