makefile中的-I标志不会导致找到头文件

时间:2016-11-14 19:52:08

标签: c++ makefile

我有一个文件./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

1 个答案:

答案 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