简体   繁体   中英

For each on target of Makefile variable

I've makefile which looks like follows

apps = app1 app2 app3

all: dir app1 app2 app3 zip cleanup

Now I want to do some loop on the list of apps varible,

something like

`loop on apps

endloop`

Is it possible in makefile to loop on it, I need to do loop on apps varible list

update

lets say this variable( apps ) is generated by my program in the make file, which provide for each project diffrent values of apps, sometimes its apps= app1 app2 sometimes its apps= app1 and sometimes can be 20 apps or more apps= app1 app2 appN

How can I iterate on apps varible and do something, for example in each iteration print something like:

now im in `app1`
now im in `app2`
etc

When trying the following

.PHONY: foo
all: foo
APPS = app1 app2 app3 app4
foo : $(APPS)
    for $$f in $(APPS); do echo $$f is here; done

I got following error:

make: *** No rule to make target app1', needed by foo'. Stop. foo'. Stop.

I see you've gone back and forth a bit, so let me just make a comment which may or may not help.

In general you don't write loops inside make recipes, because make itself provides "looping". So when you write a rule like:

all: app1 app2 app3 app4

make will try to build each one of those prerequisites, one at a time. So if you wanted to have a makefile that echoed a line for each entry in the apps variable you would do it like this:

all: $(apps)

$(apps):
        @echo $@

This tells make to start with a target all and try to "build" each of its prerequisites which are the values in the apps variable.

Then you define a rule for how to build the apps, and for each one you say that the rule is echo $@ where $@ is an automatic variable that expands to the currently-building target.

In make, the syntax:

foo bar biz:
        some command

is shorthand for, and identical to, writing:

foo:
        some command
bar:
        some command
biz:
        some command

The crucial thing when writing makefiles is that you think how to write a rule to create one file (target) from zero or more prerequisite files. Then you let make worry about how to connect all those prerequisites together and order them properly.

ETA If you want a special rule for one particular target in a long list held in the $(apps) variable, you can do this:

$(filter-out bar,$(apps)):
        @echo print $@

bar:
        some other command

Maybe you want something like (and I assume that some other part of the Makefile describes how app1 and app2 etc... should be built with appropriate rules).

foo: app1 app2 app3 app4 
     for f in $^ ; do echo $$f is here ; done

or (slightly better)

APPS = app1 app2 app3 app4
foo : $(APPS)
     for f in $(APPS); do echo $$f is here; done

and you might be interested in the foreach function in make (or perhaps its eval function , perhaps mixed with something else)

At last, your makefile (or some parts included in it) could be generated by some (shell, AWK, Python, ...) script (or even another program coded in C++, Java, Ocaml, whatever you want)

I recommend using remake , as remake -x , to debug your Makefile

You could also generate some submakefile and run $(MAKE) -f submakefile in some recipe.

I strongly recommend taking at least one hour in reading entirely the documentation of GNU make before coding something in your Makefile . And you could also need to read the documentation of bash .

At last, you might consider some other build automation tool, like ninja (whose philosophy is different : the build.ninja file is expected to be generated and you have to provide a generator for it)

For your next question, please provide some MCVE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM