makefile для компиляции всех файлов cpp во всех подкаталогах

Мой репозиторий выглядит так:

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

Я хочу создать make-файл, который будет создавать файл depndency (.d) для каждого файла .cpp в ./dep, а затем скомпилировать каждый из этих файлов .cpp в объект в ./obj

Я не хочу явно указывать имя и путь модулей — просто взять все каталоги в ./src, найти файл cpp в каждом и создать целевое правило для него.

Изменить: я использую окна.

2

Решение

Работающий минималистичный Makefile под 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)

Подкаталоги создаются в obj а также dep чтобы избежать конфликтов, если два файла имеют одинаковое имя файла, но находятся в разных подкаталогах. Это также позволяет избежать повторной компиляции исходных файлов в подкаталогах make вызывается.


ОБНОВИТЬ: Более мощная версия

ОКНА ОКНА (Vista и новее из-за FORFILE команда)

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
5

Другие решения

Один из самых простых make-файлов, которые вы можете сделать, выглядит следующим образом:

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 и скомпилирует их.

0

По вопросам рекламы [email protected]