Makefile - 重新编译

实际上make是一个智能的工具,它可以基于你在源文件中所做的更改而选择性的生效。如果你有四个文件 main.cpp、hello.cpp、factorial.cpp 和 functions.h,那么(由于顺序的原因)所有其余文件都依赖于 functions.h,而 main.cpp 依赖于 hello.cpp 和 factorial.cpp。因此,如果您在 functions.h 中进行了任何更改,则make会重新编译所有源文件以生成新的目标文件。但是,如果您在 main.cpp 中进行任何更改,因为它不被任何其他文件依赖,所以只会重新编译 main.cpp 文件,而 help.cpp 和 factorial.cpp 则不会。

其原理为,编译文件时make检查其目标文件并比较文件的更新时间戳。如果源文件比目标文件具有更新的时间戳,则假定源文件已更改,那么 make 会生成新的目标文件。

避免反复编译

可能有一个由数千个文件组成的项目。有时您可能更改了源文件,但您可能不想让所有依赖它的文件重新编译。例如,假设你添加一个宏或一个声明到其他文件所依赖的头文件中。通常make会保守地假定头文件中的任何变化都需要重新编译所有依赖于它文件,不过有时候你可能知道它们不需要重新编译,也不想浪费时间等待它们编译。

当你在更改头文件之前预见了该问题,则可以使用 “-t” 标志。该标志告诉make不用运行目标规则中的命令,而是通过修改目标文件的最后修改日期来标记它是最新的。你需要遵循这几个过程 -

  • 使用 “make” 命令重新编译真正需要重新编译的源文件。

  • 在头文件中进行更改。

  • 使用命令 make -t 将所有对象文件标记为最新。下一次运行 make 时,头文件中的更改不会导致任何反复编译。

如果你在某些文件需要重新编译时更改了头文件,那么再做这个操作就晚了(因为有需要编译的,不能全部重置,那么就需要全部重新编译了)。相反,你可以使用 -o文件 标志,该标志将指定的文件标记为“旧”。这意味着,(相关的目标)文件本身不会被重新(编译)制作(目标文件),并且其他任何内容都不会在其(递归的)依赖链上重新(编译)制作(目标文件)。你需要遵循以下过程来实现该效果 -

  • 想要重新编译特定的源文件,其依赖于特定头文件修改的情况,可以使用 make -o header file。如果涉及到多个头文件,则为每个头文件前使用单独 “-o” 选项。

  • 通过 make -t 更新所有的目标文件。