0
votes

I have a makefile as below, which can compile and link all cpp files in a same directory:

g++1x:=g++ -std=c++14 -stdlib=libc++ -MMD -MP
cflags:= -Wall -lncurses

TARGET:=matrix.out
CPPFILES:=$(wildcard *.cpp)
OBJDIRECTORY:=.obj
OBJFILES:=$(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.o)))

.PHONY: install
install: $(OBJDIRECTORY) $(TARGET)

$(OBJDIRECTORY):
    mkdir -p $(OBJDIRECTORY)

$(TARGET): $(OBJFILES)
    $(g++1x) $(cflags) -o $@ $^ -g

$(OBJDIRECTORY)/%.o: %.cpp
#%.o: %.cpp
    $(g++1x) -c -o $@ $< -g

-include $(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.d)))

.PHONY: clean
clean:
    rm -f $(TARGET)
    rm -rf $(OBJDIRECTORY)

When I execute make, a .obj will be created and all of obj files are in it. Also an executable file will be generated too. For now everything's fine.

Now I'm trying to organise my project. My plan is to create some subdirectories and each of them contains a makefile. When I execute a makefile, it will generate obj files at some fixed path. Finally, I can execute a makefile to link main.cpp and all of obj files to get the executable file.

But I don't know how to write such a makefile for subdirectory. I've made a try as below but it doesn't work.

project
   |--- main.cpp
   |--- makefile
   |--- subdir
          |--- test.h
          |--- test.cpp
          |--- makefile

Here is my makefile in project/subdir:

g++1x:=g++ -std=c++14 -stdlib=libc++ -MMD -MP
cflags:= -Wall -lncurses

CPPFILES:=$(wildcard *.cpp)
OBJDIRECTORY:=../.obj
TARGET:=$(OBJDIRECTORY)/%.o
OBJFILES:=$(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.o)))


.PHONY: install
install: $(OBJDIRECTORY) $(TARGET)

$(OBJDIRECTORY):
    mkdir -p $(OBJDIRECTORY)

$(TARGET): %.cpp
#%.o: %.cpp
    $(g++1x) -c $@ $< -g

-include $(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.d)))

.PHONY: clean
clean:
    rm $(OBJDIRECTORY)/%.o

Error:

make: *** No rule to make target ../.obj/%.o', needed byinstall'. Stop.

2
You might want to read the paper "Recursive Make Considered Harmful" at aegis.sourceforge.net/auug97.pdf. - user2100815

2 Answers

1
votes

Don't place files in the path's parent; turn the problem around: Have a Makefile in the root directory that $(MAKE)s the subdirs and uses the obj files there.

0
votes

You have several problems here.

In your original makefile, the variable TARGET contained the string "matrix.out", and all was well.

In your subdir/makefile, the variable TARGET contains the string "../.obj/%.o", and you're asking Make to build that. The only rule it can find:

$(TARGET): %.cpp
    ...

doesn't help, because there is no file called "%.cpp" anywhere.

I suggest you try something like this:

install: $(OBJFILES)

$(OBJFILES): $(OBJDIRECTORY)/%.o: %.cpp $(OBJDIRECTORY)
    $(g++1x) -c $@ $< -g

Once you get that working, you can worry about the problem of getting the master makefile to invoke the sun-makes.