如何为包含头文件的目标编写生成文件?

How to write makefile for a target that includes a header file?

本文关键字:文件 包含头 目标      更新时间:2023-10-16

我有两个文件"create-exercise.cpp"和"exercise.hpp"。我想写一个makefile来使用gnu++ 17和g ++来编译它们。exercise.hpp 包含在 create-exercise.cpp 中。我只想从创建练习中获得一个二进制文件.cpp。我将使用的命令g++ -std=gnu++17 create-exercise.cpp -o create-exercise并且运行良好。我尝试在制作文件中使用以下文件。

CXXFLAGS=-Wall -std=gnu++17
create-exercise: create-exercise.cpp exercise.hpp

但这产生了以下g++ -Wall -std=gnu++17 create-exercise.cpp exercise.hpp -o create-exercise我不希望exercise.hpp包含在编译命令中。我也尝试使用以下方法。

CXXFLAGS=-Wall -std=gnu++17
create-exercise.o: create-exercise.cpp exercise.hpp

这产生了g++ -Wall -std=gnu++17 -c -o create-exercise.o create-exercise.cpp.我不想要-c标志。因为当我尝试运行create-exercise.o时会导致权限被拒绝错误。我也尝试了以下方法:

CXXFLAGS=-Wall -std=gnu++17
create-exercise.o: create-exercise.cpp exercise.hpp
$(CXX) $(CXXFLAGS) create-exercise.cpp -o create-exercise.o

但是当我编辑时exercise.hppmake 说'create-exercise.o' is up to date.并且没有重新编译它。 我该怎么办?

在生成文件中写入的规则是:

create-exercise.o: exercise.hpp

这是一个没有配方的规则,它只是在目标create-exercise.o上增加了一个先决条件(exercise.hpp(,即每当exercise.hpp发生变化时,create-exercise.o都应该重建。

但是,提供该规则时的问题是GNU Make假定create-exercise.o是在构建create-exercise时从C源文件生成的对象文件。因此,它不会链接C++库,而是链接 C 库,这就是为什么您有对std::cout的未定义引用的喜欢错误。

GNU Make 有以下隐式规则用于从C++源文件生成可执行文件:

%: %.cpp
#  commands to execute (built-in):
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@

您可以使用该规则的配方从creating-exercise.o构建create-exercise,并仍creating-exercise.o视为从C++源文件生成的对象文件:

create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@

然后,整个生成文件将是:

CXXFLAGS = -Wall -std=gnu++17 
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@
create-exercise.o: exercise.hpp

目标create-exercise也成为默认目标,因为它是生成文件中的第一个规则。如果您不指定要make的任何内容,则它是要构建的目标。

你可以这样做:

CXXFLAGS = -Wall -std=gnu++17
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LDLIBS) -o $@
create-exercise.o: exercise.hpp

这说:从目标文件create-exercise.o构建create-exercise,如果它被更改了。 如果头文件exercise.hpp更改,它说重建create-exercise.o;如果标头更改,则修改或重建源文件是不对的。 它是依赖于标头的对象文件

制作有许多内置规则。 其中包括知道如何链接程序的规则,但不幸的是,它假设您的目标文件是从 C 文件构建的,因此如果您使用的是C++则必须创建特定的配方。 但是你仍然可以使用 GNU make 的默认变量。

它还知道如何从.cpp文件自行构建.o文件:您无需编写该配方。

我不确定,但也许尝试包含 .hpp 文件而不是与其他文件一起编译它。你可以通过使用 g++ *.cpp -I *.hpp -o 输出来做到这一点

尝试一下,让我知道它是否适合您。