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: th...@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.