https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118223
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- here is an example of how GCC handles an auto-generated file which is definitely not stored in SCM: ``` TARGET_H = $(TM_H) target.h $(TARGET_DEF) insn-modes.h insn-codes.h FLAGS_H = flags.h flag-types.h $(OPTIONS_H) OPTIONS_H = options.h flag-types.h $(OPTIONS_H_EXTRA) TM_H = $(GTM_H) insn-flags.h $(OPTIONS_H) RTL_H = $(RTL_BASE_H) $(FLAGS_H) genrtl.h ... # For each of the files generated by running a generator program over # the machine description, the following static pattern rules run the # generator program only if the machine description has changed, # but touch the target file only when its contents actually change. # The "; @true" construct forces Make to recheck the timestamp on # the target file. simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \ insn-config.h insn-flags.h insn-target-def.h simple_rtl_generated_c = insn-automata.cc \ insn-extract.cc insn-output.cc \ insn-peep.cc simple_generated_h = $(simple_rtl_generated_h) insn-constants.h simple_generated_c = $(simple_rtl_generated_c) insn-enums.cc $(simple_generated_h:insn-%.h=s-%) \ $(simple_generated_c:insn-%.cc=s-%): s-%: $(MD_DEPS) $(simple_rtl_generated_h:insn-%.h=s-%) \ $(simple_rtl_generated_c:insn-%.cc=s-%): s-%: insn-conditions.md $(simple_generated_h): insn-%.h: s-%; @true $(simple_generated_h:insn-%.h=s-%): s-%: build/gen%$(build_exeext) $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ $(filter insn-conditions.md,$^) > tmp-$*.h $(SHELL) $(srcdir)/../move-if-change tmp-$*.h insn-$*.h $(STAMP) s-$* $(simple_generated_c): insn-%.cc: s-%; @true $(simple_generated_c:insn-%.cc=s-%): s-%: build/gen%$(build_exeext) $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ $(filter insn-conditions.md,$^) > tmp-$*.cc $(SHELL) $(srcdir)/../move-if-change tmp-$*.cc insn-$*.cc $(STAMP) s-$* ... generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \ $(simple_generated_h) specs.h \ tree-check.h genrtl.h insn-modes.h insn-modes-inline.h \ tm-preds.h tm-constrs.h \ $(ALL_GTFILES_H) gtype-desc.cc gtype-desc.h version.h \ options.h target-hooks-def.h insn-opinit.h \ common/common-target-hooks-def.h pass-instances.def \ $(GIMPLE_MATCH_PD_SEQ_SRC) $(GENERIC_MATCH_PD_SEQ_SRC) \ gimple-match-auto.h generic-match-auto.h \ c-family/c-target-hooks-def.h d/d-target-hooks-def.h \ $(TM_RUST_H) rust/rust-target-hooks-def.h \ case-cfn-macros.h \ cfn-operators.pd omp-device-properties.h options.h: s-options-h ; @true s-options-h: optionlist $(srcdir)/opt-functions.awk $(srcdir)/opt-read.awk \ $(srcdir)/opth-gen.awk $(AWK) -f $(srcdir)/opt-functions.awk -f $(srcdir)/opt-read.awk \ -f $(srcdir)/opth-gen.awk \ < $< > tmp-options.h $(SHELL) $(srcdir)/../move-if-change tmp-options.h options.h $(STAMP) $@ ... # In order for parallel make to really start compiling the expensive # objects from $(OBJS) as early as possible, build all their # prerequisites strictly before all objects. $(ALL_HOST_OBJS) : | $(generated_files) # Include the auto-generated dependencies for all host objects. DEPFILES = \ $(foreach obj,$(ALL_HOST_OBJS),\ $(dir $(obj))$(DEPDIR)/$(patsubst %.o,%.Po,$(notdir $(obj)))) -include $(DEPFILES) ``` And yes this is complex