简体   繁体   English

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

[英]makefile to compile all cpp files in all subdirs

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 我想创建一个makefile,它将为./dep中的每个.cpp文件创建一个depndency文件(.d),然后将这些.cpp文件中的每一个编译成./obj中的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. 我不想明确说明模块的名称和路径 - 只需要获取./src中的所有目录并在每个目录中找到cpp文件并为其创建目标规则。

Edit: I'm using windows. 编辑:我正在使用Windows。

Working minimalist Makefile under Windows: 在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)

Subdirectories are created into obj and dep to avoid clashes if two files share the same filename but are in different subdirectories. 如果两个文件共享相同的文件名但位于不同的子目录中,则将子目录创建到objdep以避免冲突。 It also avoid having source files in subdirectories being recompiled everytime make is invoked. 它还避免在每次调用make重新编译子目录中的源文件。


UPDATE : A more powerful version 更新 :更强大的版本

WINDOWS SHELL (Vista and newer because of FORFILE command) 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 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

One of the simplest makefiles you can do is as follows: 您可以做的最简单的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,$@)

It will find all the .cpp files and compile them. 它将找到所有.cpp文件并进行编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM