0

I have seen this question and am somehow still unable to get make to properly call another Makefile. Here is my Makefile:

base:
    cd Base && $(MAKE)

Base is a sub-directory of my current directory where there is a different Makefile used to compile the files in said folder. However, when I call make, I simply get nothing to be done for base, whereas when I do cd Base && make from the command-line, I get expected behavior (i.e., compilation occurs). In case it is something wrong with the Makefile in Base, here is a copy of that as well:

CC=g++
CFLAGS=-O3 -Wall -pedantic -Werror -c
LINK=g++
LFLAGS=-O3

SRC=main.cpp
OBJ=..\lib\main.o
EXE=..\bin\test.exe

all: $(EXE)

$(EXE): $(OBJ) $(SRC)
    $(LINK) $(LFLAGS) $(OBJ) -o $(EXE)

..\lib\main.o: main.cpp
    $(CC) $(CFLAGS) $< -o $@
Community
  • 1
  • 1
  • 1
    Use `make -C dir` to call make on another directory. – Johnny Cage Jul 26 '15 at 16:06
  • @JonathanBen-Avraham: That worked perfectly. What does the `.PHONY` do? –  Jul 26 '15 at 16:08
  • http://www.gnu.org/software/make/manual/make.html#Phony-Targets – Oliver Charlesworth Jul 26 '15 at 16:09
  • See: https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html – Jonathan Ben-Avraham Jul 26 '15 at 16:18
  • If you had tried replacing `cd Base && $(MAKE)` with `echo hello`, you would have noticed that this problem has nothing to do with Make calling Make. – Beta Jul 26 '15 at 18:17
  • Just to clarify: if a target exists and has no prerequisites (or no prerequisites which are newer), then make won't build the target. It doesn't matter to make if the "target" is a file or, as in your case, a directory: only that it exists and it's older than all its prerequisites (if any). That's why declaring it to be `.PHONY` is needed. – MadScientist Jul 26 '15 at 18:49

1 Answers1

1

I'm not sure what $(MAKE) amounts to (I'm assuming just 'make'), but I have my makefiles setup in a cascading manner where one calls another in order to cover all subdirectories.

Each makefile has some common targets like 'all' and 'clean'. Then my makefiles which are just delegating to subdirs look something like this:

.PHONY : all
all:
    cd SubDir1 && make $@
    cd SubDir2 && make $@
    ...

.PHONY : clean
clean:
    cd SubDir1 && make $@
    cd SubDir2 && make $@
    ...

$@ is an automatic variable which will be substituted for the target ('all' or 'clean' in the example above).

This allows you to run 'make', 'make clean', 'make all', or even 'make clean all' from the top-level dir and it will recurse through the subdirs specified in the makefiles for the appropriate target. So if you run 'make clean' at the top, all directories in the makefile's list will be called with 'make clean'.

You can still use this technique even if you don't have common targets. Simply change the automatic variable $@ with the appropriate target for each directory's makefile.

codesniffer
  • 1,033
  • 9
  • 22