views:

119

answers:

2

The problem is fairly simple. I am trying to write a rule, that given the name of the required file will be able to tailor its dependencies.

Let's say I have two programs: calc_foo and calc_bar and they generate a file with output dependent on the parameter. My target would have a name 'target_*_*'; for example, 'target_foo_1' would be generated by running './calc_foo 1'.

The question is, how to write a makefile that would generate outputs of the two programs for a range of parameters?

A: 

This seems to do more or less what you are requesting - assuming you are using GNU Make.

Makefile

BAR_out  = target_bar_
BAR_list = 1 2 3 4 5 6 7 8 9
BAR_targets = $(addprefix ${BAR_out},${BAR_list})

FOO_out  = target_foo_
FOO_list = 11 12 13 14 15 16 17 18 19
FOO_targets = $(addprefix ${FOO_out},${FOO_list})

all: ${BAR_targets} ${FOO_targets}

${BAR_targets}:
    calc_bar $(subst ${BAR_out},,$@)

${FOO_targets}:
    calc_foo $(subst ${FOO_out},,$@)

It can probably be cleaned up, but I tested it with the commands:

calc_bar

echo "BAR $@" | tee target_bar_$@
sleep $@

calc_foo

echo "FOO $@" | tee target_foo_$@
sleep $@

Clearly, if you want a different list, you can specify that on the command line:

make -j4 FOO_LIST="1 2 3 4 5 6 33"
Jonathan Leffler
+2  A: 

If there are just a few programs, you can have a rule for each one:

target_foo_%:
    ./calc_foo $*

If you want to run a program with a list of parameters:

foo_parameter_list = 1 2 green Thursday 23 bismuth

foo_targets = $(addprefix target_foo_,$(foo_parameter_list))

all: $(foo_targets)

If you want a different set of parameters for each program, but with some in common, you can separate the common ones:

common_parameter_list = 1 2 green Thursday

foo_parameter_list = $(common_parameters) 23 bismuth

bar_parameter_list = $(common_parameters) 46 111

If it turns out you have more programs than you thought, but still want to use this method, you just want to automate it:

# add programs here
PROGRAMS = foo bar baz

# You still have to tailor the parameter lists by hand
foo_parameter_list = 1 2 green Thursday 23 bismuth

# everything from here on can be left alone

define PROGRAM_template

$(1)_targets = $(addprefix target_$(1)_,$($(1)_parameter_list))

target_$(1)_%:
    ./calc_$(1) $$*

all: $(1)_targets

endef

$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
Beta
+1. And I actually hate Make for that.
Pavel Shved
@Pavel Shved: Pavel! How good to see you again! Yes, this is pretty awful. I guess we can add `targ_%_%: \ calc_$(*1) $(*2)` to the list of things Make should do, but doesn't.
Beta