views:

309

answers:

4

(disclaimer: I am used to scons ... I am somewhat unexperienced with make)

Context: I am using Eclipse CDT which generates makefiles.

Let's say I have a project directory 'lib' and 2 build configurations 'Debug' and 'Release'. Eclipse CDT gracefully generates a makefile for each build configuration. The said makefiles end-up residing in 'Debug' and 'Release' folders.

Now, what I want to do is have a makefile in the folder 'lib' which calls the makefiles 'Debug/makefile' and 'Release/makefile'.

How do I do that?

I want to be able to launch 'make' in the folder 'lib' and both configurations would be called with the specified target(s).

Solution Based on all the great input gathered here, I devised the following:

MAKE=make
BUILDS=Release Debug
TARGETS=all clean

$(TARGETS):
    @for b in $(BUILDS) ; do $(MAKE) -C $$b $@ ; done

$(BUILDS):
    @for t in $(TARGETS) ; do $(MAKE) -C $@ $$t ; done

%:
    @for b in $(BUILDS) ; do $(MAKE) -C $$b $@ ; done
+4  A: 

depends on what is "calls". You want to either

include $(BUILD)/Makefile

or

$(MAKE) -C $(BUILD) $@

or some such. I'd guess you want the latter. Maybe something like

release debug:
    $(MAKE) -C $@

You get the idea.

More examples:

BUILDS=release debug
TARGETS=all clean

$(TARGETS):
    for b in $(BUILDS) ; do $(MAKE) -C $$b $@ ; done

$(BUILDS):
    for t in $(TARGETS) ; do $(MAKE) -C $@ $$t ; done
Michael Krelin - hacker
what does the $(BUILD) variables stand for? Is it contextual to make itself *or* am I expected to specify it?
jldupont
It was to give you an idea. Like if you have `BUILD=debug` it will go build (whatever the target is) into `$(BUILD)` - `debug` directory. Your final makefile is up to you, anyway ;-)
Michael Krelin - hacker
But I do not want to have to specify all the supported target in this 'top level' makefile: I want to pass along the targets from the command-line down to the *sub* makefiles... How do I achieve this?
jldupont
It seems that having a **%** target proves useful to helping solve my problem... the trouble is that the implicit target *all* (when just invoking *make* without parameters) does not get processed... how do I go about solving this?
jldupont
Yes, you can use wildcard targets. You can try adding `default: all` target in the very beginning of the makefile. I think that should to the trick.
Michael Krelin - hacker
and note my comment above to your question (re `$MAKE`).
Michael Krelin - hacker
+2  A: 
all: release debug

release:
   $(MAKE) -C ../Release

debug:
   $(MAKE) -C ../Debug

I'm assuming they're all on the same level. The path must be from where you call Make.

Daniel Bingham
Minor correction: the makefiles are located in *lib/Debug* and *lib/Release* so it should be **make -C Debug** and **make -C Release**.Works fine! Thanks!
jldupont
But what about specifying targets for each? I do not want to be limited to 'debug' and 'release'. Don't I need a *$@* somewhere??
jldupont
Beta's answer covers that nicely :)
Daniel Bingham
A: 

Have different targets that invoke the makefile in the two directories.

all: debug product

debug:
        $(MAKE) -f debug/Makefile

product:
        $(MAKE) -f product/Makefile
JZeeb
Doesn't account for the relative path hierarchy contained in the *sub* makefiles.
jldupont
Of course, this was an example to show you how to structure the top-level makefile. You didn't provide your sub-makefiles, so it wasn't possible to know that they contained relative paths.The projects that I work on do not rely on relative paths in the sub-makefiles, but pass additional parameters down to the sub-makefiles to identify build locations.
JZeeb
+3  A: 

Since you mention "the specified target(s)", I suggest:

%:
    $(MAKE) -C Debug $@
    $(MAKE) -C Release $@

If that's too general, you can replace the % with $(TARGETS), where TARGETS is something you define, a list of all the things you'd ever want to do this with.

Beta
Tried this but it does not work with the default command launch *make* : it complains that the target **all** isn't specified ;-(
jldupont
@Jean-Lou Dupont: you just need to add `all: debug release` to the beginning of the makefile provided by Beta.
Pavel Shved