How about using pattern substitutions? Something like:
#-------------------------------------------------------------------# default: all #--------- Inputs ------------# INPUTS := in1.input in2.input in3.input SECOND_INPUTS := second_in1.input second_in2.input second_in3.input $(INPUTS) $(SECOND_INPUTS): touch $@ #------ Intermediates --------# INTERMEDIATES := $(patsubst %.input,%.intermediate,$(INPUTS)) %.intermediate: %.input cp $< $@ #--------- Outputs -----------# OUTPUTS := $(patsubst %.input,%.output,$(SECOND_INPUTS)) all: $(OUTPUTS) %.output: %.input $(INTERMEDIATES) cp $< $@ #---------- Misc ------------# clean: rm -f *.output *.intermediate distclean: rm -f *.input *.output *.intermediate .DELETE_ON_ERROR: .INTERMEDIATE: $(INTERMEDIATES) On Thu, Jan 15, 2015 at 4:15 AM, Luke Goodsell <luke.goods...@ogt.com> wrote: > Hi, > > Thanks in advance for taking the time to read and reply to my email. > > $ make --version > GNU Make 4.0 > Built for x86_64-pc-linux-gnu > > Abstract: > > I'm writing a template makefile for performing similar - but different - > computational biology pipelines and am encountering an issue with recursive > implicit rules. Please can you suggest a solution that doesn't require > explicitly listing every intermediate target? > > Background: > > I'm writing a Makefile template that can be used for new projects. Each > project follows a very similar, path but with differences that must be > manually adapted. Each project has to perform similar tasks on each of > number of different 'sections', each of which has a number of different > 'groups' that each have a number of 'steps'. Each step cannot be run until > the previous step has run. The same is true of groups and sections. > > Problem: > > The first group of the first section runs fine, with all steps running > without error. However, the second group of the first section - and all > subsequent targets - fails with: > > make: *** No rule to make target '[TARGET]'. Stop. > > I understand that an implicit rule cannot be used multiple times within a > chain, and that the standard solution is to explicitly declare an > intermediate. However, since this makefile template may have tens each of > steps, groups and sections, that would require hundreds to thousands of > explicitly declared intermediates. > > Is there a better solution I've overlooked? > > Addendum: > > A prototypical makefile that demonstrates the problem is pasted below. > > Kind regards, > Luke > > > # Example makefile > # I want to be able to be able to `make all` without explicitly listing all > # intermediate steps. The first target that fails is > # section/section1/group2/step1/do_step > > all: \ > section/section2/section_end \ > > echo "$@"; > > section/section1/section_start: \ > > echo "$@"; > > section/section2/section_start: \ > section/section1/section_end > > echo "$@"; > > # eg: section/section1/group1/group_start > section/%/group1/group_start: \ > > echo "$@"; > > # eg: section/section1/group2/group_start > section/%/group2/group_start: \ > section/%/group1/group_end \ > > echo "$@"; > > # eg: section/section1/group1/step1/do_step > # eg: section/section1/group2/step1/do_step > section/%/step1/do_step: \ > section/%/group_start \ > > echo "$@"; > > # eg: section/section1/group1/step2/do_step > section/%/step2/do_step: \ > section/%/step1/do_step \ > > echo "$@"; > > # eg: section/section1/group1/step3/do_step > section/%/step3/do_step: \ > section/%/step2/do_step \ > > echo "$@"; > > # eg: section/section1/group1/group_end > section/%/group_end: \ > section/%/step3/do_step \ > > echo "$@"; > > # eg: section/section1/section_end > section/%/section_end: \ > section/%/group2/group_end \ > > echo "$@"; > > > > _______________________________________________ > Help-make mailing list > Help-make@gnu.org > https://lists.gnu.org/mailman/listinfo/help-make > -- Nicholas Clark Email: nicholas.cl...@gmail.com _______________________________________________ Help-make mailing list Help-make@gnu.org https://lists.gnu.org/mailman/listinfo/help-make