Reputation: 3856
My repository looks like this:
./src/ModuleA/ModuleA.cpp
./src/ModuleA/ModuleA.h
./src/foo/ModuleB.cpp
./src/foo/ModuleB.h
./src/bar/ModuleC.cpp
./src/bar/ModuleC.h
<A few more modules>
./obj
./dep
./makefile
I want to create a makefile that will create a depndency file (.d) for each .cpp file into ./dep and then compile each of these .cpp file into an obj in ./obj
I don't want to state the name and path of the modules explicitly - just to take all of the directories in ./src and find the cpp file in each one and create a target rule for it.
Edit: I'm using windows.
Upvotes: 3
Views: 6063
Reputation: 10456
Working minimalist Makefile under Windows:
SRC := $(patsubst $(shell CHDIR )\\%.cpp,%.cpp,$(shell DIR *.cpp /S /B))
OBJ := $(addprefix obj\, $(SRC:.cpp=.o))
DEP := $(addprefix dep\, $(SRC:.cpp=.d))
CPPFLAGS = -MMD -MP -MF dep\$(<:.cpp=.d)
all: $(OBJ)
obj\\%.o: %.cpp
@IF NOT EXIST obj\$(<D) MKDIR obj\$(<D)
@IF NOT EXIST dep\$(<D) MKDIR dep\$(<D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
-include $(DEP)
Subdirectories are created into obj
and dep
to avoid clashes if two files share the same filename but are in different subdirectories. It also avoid having source files in subdirectories being recompiled everytime make
is invoked.
UPDATE: A more powerful version
WINDOWS SHELL (Vista and newer because of FORFILE
command)
SRCDIR := .
OBJDIR := obj
DEPDIR := dep
SRCS := $(shell FORFILES /P $(SRCDIR) /S /M *.cpp /C "CMD /C ECHO @relpath")
SRCS := $(patsubst ".\\%",$(SRCDIR)\\%,$(SRCS))
OBJS := $(SRCS:$(SRCDIR)\\%.cpp=$(OBJDIR)\\%.o)
DEPS := $(SRCS:$(SRCDIR)\\%.cpp=$(DEPDIR)\\%.d)
TREE := $(patsubst %\,%,$(dir $(OBJS)))
CPPFLAGS = -MMD -MP -MF $(<:$(SRCDIR)\\%.cpp=$(DEPDIR)\\%.d)
.PHONY: all clean
all: $(OBJS)
.SECONDEXPANSION:
$(OBJDIR)\\%.o: $(SRCDIR)\%.cpp | $$(@D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
$(TREE): %:
MKDIR $@
MKDIR $(@:$(OBJDIR)%=$(DEPDIR)%)
clean:
IF EXIST $(OBJDIR) RMDIR /S /Q $(OBJDIR)
IF EXIST $(DEPDIR) RMDIR /S /Q $(DEPDIR)
ifeq "$(MAKECMDGOALS)" ""
-include $(DEPS)
endif
UNIX SHELL
SRCDIR := .
OBJDIR := obj
DEPDIR := dep
SRCS := $(shell find $(SRCDIR) -name "*.cpp")
OBJS := $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
DEPS := $(SRCS:$(SRCDIR)/%.cpp=$(DEPDIR)/%.d)
TREE := $(patsubst %/,%,$(dir $(OBJS)))
CPPFLAGS = -MMD -MP -MF $(@:$(OBJDIR)/%.o=$(DEPDIR)/%.d)
.PHONY: all clean
all: $(OBJS)
.SECONDEXPANSION:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $$(@D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
$(TREE): %:
mkdir -p $@
mkdir -p $(@:$(OBJDIR)%=$(DEPDIR)%)
clean:
$(RM) -r $(OBJDIR) $(DEPDIR)
ifeq "$(MAKECMDGOALS)" ""
-include $(DEPS)
endif
Upvotes: 6
Reputation: 1
One of the simplest makefiles you can do is as follows:
OBJDIR = .srcobjs
SRCS := $(shell find . -name '*.cpp')
SRCDIRS := $(shell find . -name '*.cpp' -exec dirname {} \; | uniq)
OBJS := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SRCS))
DEPS := $(patsubst %.cpp,$(OBJDIR)/%.d,$(SRCS))
DEBUG = -g
INCLUDES = -I./Include
CXXFLAGS = $(DEBUG) -Wall -pedantic $(INCLUDES) -c
DEPENDS = -MT $@ -MD -MP -MF $(subst .o,.d,$@)
It will find all the .cpp files and compile them.
Upvotes: 0