Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gnu make: how to automatically list and build all targets

Tags:

makefile

Suppose I have the following Makefile:

RM = rm -f
FLAGS =  -Cr -O1 -gv -gw -g -vw
builddir = ./build/
TD = ./tasks/

all: example1 example3 example5

example1:  

    fpc 01_Kreisumfang.pas $(FLAGS) -o$(builddir)01_Kreisumfang

example3:

    fpc 03_EuroBetrag3.pas $(FLAGS) -o$(builddir)03_EuroBetrag3

example5:

    fpc 05_Dreiecke.pas $(FLAGS) -o$(builddir)05_Dreieck

clean:

    $(RM) $(builddir)*

At a certain point my Makefile grows to example112 ..., is there a way to define all automatically with out needing to type in all the targets? I don't want to do this:

all: example1 example3 example5 ... example112

Can I do something like this?

all: (MAGIC to Exclude clean)?

So instead of having to type all the targets, I want make to detect all the targets and exclude a certain list.

update:

I found the following possible hint:

 make -rpn | sed -n -e '/^$/ { n ; /^[^ ]*:/p }' |egrep -v -E '(all|clean)' 

I don't know how to make this a target by itself, I tried with:

TARGETS =: $(shell make -rpn | sed -n -e '/^$$/ { n ; /^[^ ]*:/p }' |egrep -v -E '(all|clean)')

But it seems to be wrong. Not only it is wrong, it will cause a silly recursion.

So this solution is only available as a shell command, not within the Makefile itself.

Well, make seems to be just cryptic here. The most reasonable solution I found is to create a script and use that:

$ cat doall.sh 
#!/bin/bash
for i in `make -rpn | sed -n -e '/^$/ { n ; /^[^ ]*:/p }' | sed -e 's/://' | egrep -v -E '(all|clean)'`; 
    do make $i; 
done

It seems impossible to create it as a make target, or that the ROI on this is very low ...

like image 322
oz123 Avatar asked Sep 29 '13 09:09

oz123


1 Answers

I tried this out using a for loop. Check if this simple example works for you. Took the command from this post.

RM = rm -f
FLAGS =  -Cr -O1 -gv -gw -g -vw
builddir = ./build/
TD = ./tasks/
SHELL := /bin/bash

targets=$(shell for file in `find . -name '*.pas' -type f -printf "%f\n" | sed 's/\..*/\.out/'`; do echo "$$file "; done;)

all: $(targets)

%.out:%.pas
  fpc $< $(FLAGS) -o (builddir)$@

clean:
    $(RM) $(builddir)*
like image 95
el_tenedor Avatar answered Oct 04 '22 19:10

el_tenedor