makefile编译所有子目录中的所有cpp文件

时间:2014-11-18 18:57:11

标签: c++ makefile subdirectory

我的存储库看起来像这样:

./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

我想创建一个makefile,它将为./dep中的每个.cpp文件创建一个depndency文件(.d),然后将每个.cpp文件编译成一个obj in ./obj

我不想明确说明模块的名称和路径 - 只需要获取./src中的所有目录并在每个目录中找到cpp文件并为其创建目标规则。

编辑:我正在使用Windows。

2 个答案:

答案 0 :(得分:5)

在Windows下使用极简主义Makefile:

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)

子目录创建到objdep以避免冲突,如果两个文件共享相同的文件名但位于不同的子目录中。它还避免每次调用make时重新编译子目录中的源文件。


更新:更强大的版本

WINDOWS SHELL (由于FORFILE命令,Vista和更新版本)

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

答案 1 :(得分:0)

您可以做的最简单的makefile之一如下:

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,$@)

它将找到所有.cpp文件并进行编译。