【问题标题】:How to write a Makefile (for a c++ project) with a header in the parent directory?如何在父目录中编写带有标题的 Makefile(用于 c++ 项目)?
【发布时间】:2021-04-04 02:54:39
【问题描述】:

我目前正在努力制作,非常感谢任何提示或教程。 我的项目文件夹结构如下:

/project
  bar.hpp
  /folder1
    main.cpp // #include "foo.hpp"  #include "bar.hpp"
    foo.cpp  // #include "foo.hpp"  #include "bar.hpp"
    foo.hpp  // #include "bar.hpp"
    Makefile

当从文件夹 1 调用时编译。

g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -I../ main.cpp foo.cpp

我编写了以下 Makefile,但它没有按我的预期工作:

CXX = g++-10
CXXFLAGS = -std=c++2a -O3 -fno-pic -no-pie -Wall
CPPFLAGS = -I../

.PHONY : all clean distclean

EXE = a.out
SRC = main.cpp foo.cpp
OBJ = $(SRC: .cpp=.o)
INC = $(wildcard *.hpp) ../bar.hpp

all : $(EXE)

clean :
    $(RM) *.o

distclean : clean
    $(RM) $(EXE)

$(EXE) : $(OBJ)
    $(CXX) $(CXXFLAGS) $^ -o $@

$(OBJ) : $(INC) // I hope this means that all object files depend on all header files?

%.o : %.cpp $(INC)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ 

我正在从文件夹 1 中调用 make all,但它不起作用。

我试图寻找 c++ make 教程,但找不到任何深入的隐式和模式规则。

这是我得到的错误

g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall main.cpp foo.cpp -o a.out
main.cpp:1:10: fatal error: bar.hpp: No such file or directory
    1 | #include "bar.hpp"
      |          ^~~~~~~~~
compilation terminated.
In file included from foo.cpp:1:
foo.hpp:1:10: fatal error: bar.hpp: No such file or directory
    1 | #include "bar.hpp"
      |          ^~~~~~~~~
compilation terminated.

我尝试在文件夹 1 中运行这些命令,并且编译正常。

g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -c foo.cpp -o foo.o -I../
g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -c main.cpp -o main.o -I../
g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall -o main main.o foo.o

【问题讨论】:

  • 你说不行。你能分享错误信息吗?这可能有助于我们诊断问题
  • g++-10 -std=c++2a -O3 -fno-pic -no-pie -Wall main.cpp foo.cpp -o a.out 它尝试执行这一行,并说找不到那个 bar.hpp。我不明白为什么它会尝试从跳过 .o 文件的 .cpp 文件构建 a.out。

标签: c++ makefile compilation linker gnu-make


【解决方案1】:

这一行是错误的:

OBJ = $(SRC: .cpp=.o)

通过在.cpp 之前添加一个空格,您的意思是OBJ 应该将变量SRC 中以“ .cpp”结尾的所有单词替换为结尾.o。但是变量SRC中没有以“ .cpp”结尾的词,所以没有做任何修改,OBJ的值与SRC的值相同。

所以,你的规则是:

a.out : main.cpp foo.cpp

所以没有构建.o 文件,因为您的目标不依赖它们。

删除空格:

OBJ = $(SRC:.cpp=.o)

【讨论】:

  • 非常感谢,有什么教程或参考可以理解这样的规则吗?在模式定义 %o : %.cpp $(INC) 上添加 $(INC) 也是多余的吗?
  • 这里有 GNU make 手册。在编写 makefile 时,您应该完全按照此处所示使用操作描述:在过去没有任何空格的地方添加空格可以改变事物的含义。是的,这是多余的,因为您已经指定了 $(OBJ) : $(INC),所以您不需要在模式规则中使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多