[Bug other/118223] New: Improve autodependency generation to avoid full product build
thutt@harp-project.com
gcc-bugzilla@gcc.gnu.org
Sat Dec 28 00:24:07 GMT 2024
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118223
Bug ID: 118223
Summary: Improve autodependency generation to avoid full
product build
Product: gcc
Version: 11.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: other
Assignee: unassigned at gcc dot gnu.org
Reporter: thutt@harp-project.com
Target Milestone: ---
Autodependency generation (-MMD) is a nice feature, but there is one
dimension that presents a less-than-spectacular interface for the
user: when a header file that is included in an auto-generated
dependency file for a project is deleted.
Generally when one of a project's header files is deleted, and 'make'
is executed, an unpleasant error is produced:
make: *** No rule to make target 'hello.h', needed by 'hello.o'.
make: Target 'hello' not remade because of errors.
This isn't bad on a small project, but on large projects with many
people (who are probably not familiar with the build system), the only
practical resort is to perform a clean, and then rebuild the entire
project. With large projects, taking long amounts of time to build,
this is objectionable.
If the autodependency generation is output with Gnu Make* in mind,
several options could be used to provide a better result for a user of
the build system (not a developer intimately familiar with the
Makefiles!):
1. Use $(wildcard) to check for the existence of each file, and
produce an error with instructions on how to clean up:
Consider, this hello.d:
hello.o: hello.c hello.h
It could become:
$(if $(wildcard hello.h),,$(error hello.h does not exist. \
Execute 'rm <path of hello.d>' and reexecute build command.))
The build would be able to proceed incrementally, and any sources
still using the missing file would fail with a better error from
the compiler about the missing file.
2. Set source file to be .PHONY.
If the header file is not found, using $(wildcard), the source file
can be set to .PHONY, and it will be automatically out-of-date with
respect to its output -- for the current invocation of the build
process only. It will be rebuilt, and the compiler will produce an
error that the header cannot be found; this is better than Make
indicating that the header file cannot be remade.
This would look something like this, for hello.d:
$(if $(wildcard hello.h),,.PHONY: hello.c)
hello.o: hello.c $(wildcard hello.h)
When the hello.c is updated to no longer reference the deleted
'hello.h', it will be out-of-date & rebuilt, and then it will be
up-to-date with respect to 'hello.o'.
Both of these would incur a little bit of extra processing during the
build process, but the overall robustness of the build process would
be improved, and deleting a project's header file would be quickly
repairable (option 1), or self-healing (option 2).
The biggest benefit of this would be all the other team members who
_already_ have 'hello.d', and sync their source tree beyond the
deletion of hello.h; their builds would not be broken, and they would
be able to continue development without having to perform a clean
build.
I believe option 2 is the better choice; deleting the header in the
SCM would require every developer with an already-built project to
provide manual repair, but option 2 just heals the build.
* If Gnu Make is not a requirement for the output of -MMD, then maybe
-MMDg or something similar could be added to include the Gnu
Make-specific output.
More information about the Gcc-bugs
mailing list