SoftTimur
SoftTimur

Reputation: 5540

Restructure makefile to avoid redundant implementation

A part of my makefile is as follow:

list1:          all
                for f in \
                `less fetch/list1.txt`; \
                do \
                    ...
                    ./$(BIN) $$f & \
                    ...
                done

list2:          all
                for f in \
                `less fetch/list2.txt`; \
                do \
                    ...
                    ./$(BIN) $$f & \
                    ...
                done

fetch/list1.txt and fetch/list2.txt contains two lists of files (path+filename), and make list1 and make list2 will respectively go through the 2 lists and run $(BIN) again the files. This works fine.

The problem is that, I have a couple of file lists as list1 and list2, and the process of the make is always the same. Does anyone know how to simplify makefile such that make listA, make list4, etc. does what they are supposed to do?

Upvotes: 1

Views: 66

Answers (3)

Loki Astari
Loki Astari

Reputation: 264669

How about:

all:
        @echo "All"

action_%:
    @./$(BIN) $*

ACTION=$(patsubst %,action_%,$(shell cat $(ACT_FILE)))

actionList:
    @make $(ACTION)

list%:  all
    @make ACT_FILE=fetch/list$*.txt actionList

Supports all list :-)

Rather than allow infinite parallelism (you were using ./$(BIN) fileName &). You can control actual parallelism using Make's built in features.

 make -j8 list1
 #      ^  Parallelism set to 8

Upvotes: 0

petrus4
petrus4

Reputation: 614

I do not recommend performing scripting within makefiles. It will very often lead to arbitrary, inconsistent bugs, and other forms of frustration.

Use Make for execution control with dependencies, (as in, determining what gets executed when) but write your actual primitives (scripts or other programs) seperately, and call them from within Make.

bar:    foo1 foo2 foo3

# bar is the make target.  Foo1, 2, and 3 are sub-targets needed to make bar.

foo1:
    fooscript1    # Written as an individual script, outside Make.
    fooscript2

Upvotes: 0

Digital Trauma
Digital Trauma

Reputation: 16016

You can use a Pattern Rule:

all:
    @echo "The all recipe"

list%: all
    @echo "This recipe does something with [email protected]"

Output is:

$ make list1
The all recipe
This recipe does something with list1.txt
$ make list256
The all recipe
This recipe does something with list256.txt
$ 

Upvotes: 1

Related Questions