我有一个文件./src/test.cpp:
#include "test.h"
void Hi() {
std::cout << "Hi, indeed..." << std::endl;
}
test.h位于./include文件夹中。
这是我的makefile:
CC = g++
CFLAGS = -Wall
INCLUDES = -I./include
SRCS = $(shell find ./src/ -name '*.cpp')
.PHONY: clean depend
OBJS = $(SRCS:.cpp=.o)
OBJS := $(OBJS:./src%=.%)
release: $(OBJS)
$(CC) $(CFLAGS) -o app_name $(OBJS)
VPATH = ./src
../%.o: %.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c $*.cpp
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ > ./.depend;
include .depend
结果我收到一个错误:
g++ -c -o test.o ./src/test.cpp
./src/test.cpp:1:18: fatal error: test.h: No such file or directory
compilation terminated.
<builtin>: recipe for target 'test.o' failed
make: *** [test.o] Error 1
文件.depend
也完全为空。
如何解决问题? makefile位于根目录:
./
makefile
./src/
test.cpp
main.cpp
./include/
test.h
答案 0 :(得分:0)
G.M.试图说你已经定义了一个模式规则,它知道如何构建一个匹配模式../%.o
的目标。但是,当你要求make构建对象时,它们的格式为./xxx.o
;例如,之后:
SRCS = $(shell find ./src/ -name '*.cpp')
假设SRCS
包含./src/foo.cpp
。在此之后:
OBJS = $(SRCS:.cpp=.o)
OBJS := $(OBJS:./src%=.%)
OBJS
将包含值./foo.o
(顺便说一句,获得此行为的更简单方法是使用patsubst
函数:$(patsubst ./src/%.cpp,./%.o,$(SRCS))
)。
因此,make将尝试构建文件./foo.o
。由于没有明确的规则,它将寻找隐含的规则。
它会看到您的模式规则,但是说明如何构建与目标文件make不匹配的../%.o
想要构建./foo.o
,因此您的规则将被忽略。
然后make会查找其他一些隐式规则,它会找到知道如何从.o
文件构建.cpp
文件的内置规则,它将使用它。该规则不使用您的变量$(INCLUDES)
,因此您的编译失败。
如果您确实希望目标文件显示在父目录中,则需要修复OBJS
设置以创建../foo.o
而不是./foo.o
等文件名,否则请更改模式规则构建%.o
而非../%.o
。