On 10/02/10 00:47, Jonah Bishop wrote:
On Tue, Feb 9, 2010 at 4:45 PM, Paul Smith <[email protected]
<mailto:[email protected]>> wrote:

    On Tue, 2010-02-09 at 16:32 -0500, Jonah Bishop wrote:
     > I'd like to do what I think should be very simple, but I can't find
     > any examples of what I'm trying to do. I have a variable in a make
     > file that has a bunch of directory names in it, and I'd like to
     > perform multiple actions on those directory names, namely by
    "looping"
     > over the list. The "foreach" construct was what I went to initially,
     > and might be the right goods, but I can't figure out the right
    syntax.

     > DIRS = alpha bravo charlie delta foxtrot
     >
     > All I want to do is "loop" over that list, performing some shell
     > operations (or issuing other commands) on those directories. Is there
     > a simple way to do that?

    The simplest way is to use shell constructs:

            dostuff:
                    for dir in $(DIRS); do \
                            stuff-1 $$dir ; \
                            stuff-2 $$dir ; \
                    done

    There are a lot of sub-optimal things about this, such as no parallel
    capability, no error handling, etc. but without more details about what
    you really want to do that's the simplest solution that will solve your
    problem.



Here's some more information that may be helpful. I have a bunch of
child directories that each have their own makefiles. I want to iterate
over a list of those directories, changing into each, and issuing the
appropriate make call in each. Similarly, I'd like to have a "make
clean" target to do the same thing: loop over the directories and do the
appropriate "make clean" call.

Hopefully that makes things a little clearer.

One way to do so is to forward top level makefile target to each of the child makefiles, like this:

[...@truth tmp]$ cat Makefile
dirs := A B
# default target
all : $(dirs)
$(dirs) : ; $(MAKE) -C $@ $(MAKECMDGOALS)
# build any target by forwarding to $(dirs) rule
% : $(dirs) ;
.PHONY: $(dirs) all

[...@truth tmp]$ cat A/Makefile
all :
% : ; @echo "updating $@"

[...@truth tmp]$ cat B/Makefile
all :
% : ; @echo "updating $@"

[...@truth tmp]$ make
make -C A
make[1]: Entering directory `/home/max/tmp/A'
updating all
make[1]: Leaving directory `/home/max/tmp/A'
make -C B
make[1]: Entering directory `/home/max/tmp/B'
updating all
make[1]: Leaving directory `/home/max/tmp/B'
make: Nothing to be done for `all'.

[...@truth tmp]$ make clean
make -C A clean
make[1]: Entering directory `/home/max/tmp/A'
updating clean
make[1]: Leaving directory `/home/max/tmp/A'
make -C B clean
make[1]: Entering directory `/home/max/tmp/B'
updating clean
make[1]: Leaving directory `/home/max/tmp/B'
make: `clean' is up to date.

[...@truth tmp]$ make clean all
make -C A clean all
make[1]: Entering directory `/home/max/tmp/A'
updating clean
updating all
make[1]: Leaving directory `/home/max/tmp/A'
make -C B clean all
make[1]: Entering directory `/home/max/tmp/B'
updating clean
updating all
make[1]: Leaving directory `/home/max/tmp/B'
make: `clean' is up to date.
make: Nothing to be done for `all'.

One interesting property of the top level forwarding makefile is that it allows for parallel execution (-j option) when child makes get invoked in parallel. If build order is required that can be specified as make dependencies, like this:

# update B only after updating A has completed
B : A

--
Max



_______________________________________________
Help-make mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-make

Reply via email to