C++中修改的.h文件不需要重新编译?

Changed .h file in C++ does not need to be compiled again?

我有以下问题。编译成功后,如果我只更改其中一个.h文件中的一些内容后再次编译,计算机会显示:

make: ‘all’ 无事可做。

即使我只修改了 .h 文件,我可以强制编译器重新编译吗?

听起来你的 Makefile 没有正确配置依赖项。这就是您应该考虑修复的问题。

如果您真的只想强制重建而不是修复根本问题。然后你可以在 make all 之前做一个 make clean 或者,如果 Makefile 没有 "clean" 目标,删除所有生成的目标文件和 libs/executables 然后 运行 make all 再一次。

您可以使用 --always-make 命令行选项强制 make 重建所有内容。

但是,听起来您没有在 Makefile 中正确设置依赖项。如果您的代码(.cpp 文件)实际上包含 headers,那么通常您编译它们的目标应该在它包含的 header 文件上有先决条件。

如果您希望在头文件更改时更新您的输出,那么您必须将它添加到您的依赖语句中:

 myprogram: myprogram.cpp myprogam.h
      c++ -o myprogram myprogram.cpp

通常我们不会这样做,因为执行任务的代码保留在 cpp 文件中。如果您使用的是 unix 并且想要强制重建,只需触摸一个 cpp 文件以使用 "touch myprogram.cpp" 更新其时间戳(强制重建),例如,或者删除您现有的可执行文件。

如果您在没有 Makefile 的情况下使用 make,让它推断依赖关系,它可能不会推断头文件依赖关系。在这种情况下,要么删除您的可执行文件,要么修改您的源文件。

Can I force the compiler to compile again even if I have only modified the .h files?

是的......但你可能想改进你的制作(工具)。

我所做的是强制对有问题的文件进行最新编译,其中显示了 make 生成的命令。

示例:

# ... noise 

g++ -O3 -ggdb -std=c++14 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -Wcast-align -Wcast-qual -Wconversion -Wpointer-arith -Wunused -Woverloaded-virtual   -O0  lmbm101_11.cc -o lmbm101_11 -L../../bag -lbag_i686 -lnet_i686 -lposix_i686 -lzlib_i686 -lrt -pthread

# ...  more noise.

为了强制构建,我突出显示了 "command" make created(从 "g++" 开始,位于噪声和更多噪声之间),并调用它而不是 make。

在 Linux 上使用 emacs 这很简单。在其他系统上可能不那么容易。

您可以考虑将此命令复制到文件中,以备将来使用。

(即我绕过 make,直到我选择修复我​​的 make 文件。)

有比接受的答案更简单的方法。只需将 -MD 添加到 Makefile 中的编译器标志,并在 Makefile 的末尾添加 -include myfile.d (改为列出所有扩展名为 *.d 的源文件)。当你 make 时,这将分别在你的构建文件夹中生成和引用额外的 *.d 依赖文件(无论你的 *.o 文件在哪里),所以你不需要明确地将每个头文件添加到你的 makefile依赖项。

这对于包含一长串头文件的项目很有用。此外,通过这种方式,您知道您不能忘记在您的 Makefile 依赖项中包含一个头文件,以防止以后当您认为您的二进制文件在您更改头文件时更新了,但实际上并没有因为您忘记了而浪费了故障排除时间将其放入 Makefile 中。

例如,使用 gcc -MD -I. -c myfile.cpp -o obj/myfile.o,您可以将 Makefile 依赖项保持为 foo: myfile.cpp 而无需 myfile.h

执行此操作的快捷方式,因此您只需列出所有文件一次,如下所示:

# Beginning of Makefile etc. etc.

# Only need to list all files once, right here.
SRCS = myfile.cpp myfile2.cpp

OBJS = $(SRCS:%.cpp=%.o)

# put .o and .d files in ./obj/
# (Assumes 'obj' directory exists)
FULLOBJS = $(addprefix obj/,$(OBJS))

# rule to make object (*.o) files
$(FULLOBJS): obj/%.o:%.cpp
    gcc -MD -I. -c %< -o $@

# rule to make binary
foo: $(FULLOBJS)
    g++ -o $@ $(FULLOBJS)

# rule to clean (Note that it also deletes *.d files)
.PHONY: clean
clean:
    rm -rf obj/*.o obj/*.d foo

# include dependency files (*.d) if available
-include $(FULLOBJS:%.o=%.d)