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

-I flag in the makefile does not result in a header file being found

本文关键字:文件 中的 标志 makefile      更新时间:2023-10-16

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

gm想说的是你已经定义了一个模式规则,它知道如何构建一个匹配模式../%.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。因为没有明确的规则,所以它会寻找一个隐含的规则。

它看到你的模式规则,但是它说的是如何构建../%.o,这与make想要构建./foo.o的目标文件不匹配,所以你的规则被忽略。

然后make会去寻找一些其他隐式规则,它会找到内置规则,知道如何从.cpp文件构建.o文件,它将使用它。该规则没有使用变量$(INCLUDES),所以编译失败。

您需要修复您的OBJS设置,以创建像../foo.o而不是./foo.o这样的文件名,如果您真的希望您的目标文件出现在父目录中,或者更改您的模式规则以构建%.o而不是../%.o