1

This is my contrived Makefile to illustrate my question:

allinfiles = file1.in file2.in file3.in

alloutfiles = file1.out file2.out file3.out

all: $(alloutfiles)

clean:
        -rm *.pyc *.in *.out > /dev/null 2>&1

# my.py generates file1.in file2.in file3.in
$(allinfiles): my.py; python my.py

%.out: %.in
        cp $< $@

My contrived Python script:

#!/usr/bin/env python

for i in 1,2,3:
    filename = 'file{}.in'.format( i )
    f = file( filename, 'wt' )
    f.write( filename )
    f.close()

Result:

$ make clean; make -j 8
python my.py
python my.py
python my.py

Question 1: how do I write my rules so that my.py is executed only once since it generates all the .in files?

NB: Unless I misunderstood, I'm trying to use this answer and not getting the results I expected.

Question 2: is there a way to log all the build outputs by their target? That is, if instead of $(shell cp $< $@), the recipe generated much output, how do I separate the output by target or input file?

Community
  • 1
  • 1
John Schmitt
  • 1,148
  • 17
  • 39
  • 1
    Using `$(shell)` in a recipe line is incorrect. You just want `cp $< $@` there as you are already in a shell context. The timing of the commands differs. `$(shell)` will be executed when the recipe is expanded but the inline `cp` will occur when that line of the recipe is executed... or at least I believe that is true I would need to test it to be sure. – Etan Reisner Apr 03 '15 at 20:58
  • You need to teach make that all the files are generated by the same invocation of `my.py` assuming that's what you mean. The multiple pattern targets rule does that but it isn't clear how best for you to use that here. – Etan Reisner Apr 03 '15 at 20:59
  • This isn't a parallelism issue. The only way in _make_ to write a rule that updates more than one target in a single invocation is to use a pattern rule. See http://stackoverflow.com/questions/19822435/multiple-targets-from-one-recipe-and-parallel-execution for instance. – bobbogo Apr 15 '15 at 06:48

0 Answers0