我正在尝试为我的项目创建一个makefile,但我似乎遇到了一些错误,因为我正在测试新的东西。我的文件结构是这样的:
~/main #root project folder
~/main/include #header files (mostly class headers)
~/main/src #source files
~/main/src/obj #object files
Makefile
(Makefile位于根项目文件夹中)
生成文件:
CC=g++
IDIR=include
SDIR=src
ODIR=src/obj
DEPS=$(IDIR)/%.h
OBJS=$(ODIR)/%.o
SRCS=$(SDIR)/%.cpp
CFLAGS=-Wall -std=c++11 -I$(IDIR)
$(OBJS): $(SRCS) $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
all: $(OBJS)
gcc -o run $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(OBJS)
出于测试目的,我在main.cpp
文件夹中有一个src
,在include
文件夹中有一个随机头文件。运行简单make
命令时出现的错误如下:
make: *** No rule to make target `src/obj/%.o', needed by `all'. Stop.
编辑:在下面的家伙的帮助下,我想出了解决方案
CC=g++
IDIR=include
SDIR=src
ODIR=src/obj
CFLAGS=-Wall -std=c++11 -I$(IDIR)
_DEPS = yo.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
_SRC = main.cpp
SRC = $(patsubst %,$(SDIR)/%,$(_SRC))
$(ODIR)/%.o: $(SRC) $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
all: $(OBJ)
$(CC) -o run $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(OBJS)
答案 0 :(得分:2)
在两种情况下使用%
会有所不同。当你写:
$(ODIR)/%.o : $(SDIR)/%.cpp $(IDIR)/%.h
将进行模式替换,并创建一系列规则,如:
$(ODIR)/foo.o : $(SDIR)/foo.cpp $(SDIR)/foo.h
所以它很好,虽然您应该明确使用%
,以便明白该规则正在做什么。
但是当你在这里使用它时:
all : $(ODIR)/%.o
这实际上是在寻找您没有规则的目标$(ODIR)/%.o
。没有替代品。并且你没有规则来制定目标 - 因此错误。您打算做的是让all
依赖于您想要使用wildcard
函数的所有实际对象:
SOURCES = $(wildcard $(SDIR)/*.cpp)
OBJECTS = $(SOURCES:$(SDIR)/%.cpp=$(ODIR)/%.o)
all : $(OBJECTS)
gcc -o run $^ $(CFLAGS)
答案 1 :(得分:1)
使用时
OBJS=$(ODIR)/%.o
%.o
部分没有扩展到任何有意义的东西。它只是字面值%.o
。 DEPS
和SRCS
也存在同样的问题。
您需要使用wildcard
和patsub
功能。而不是
DEPS=$(IDIR)/%.h
OBJS=$(ODIR)/%.o
SRCS=$(SDIR)/%.cpp
使用
DEPS=$(wildcard $(IDIR)/*.h)
SRCS=$(wildcard $(SDIR)/*.cpp)
OBJS=$(patsub %.cpp,%.o,$(SRCS))