为啥外部包含目录编译多次?

Posted

技术标签:

【中文标题】为啥外部包含目录编译多次?【英文标题】:Why external include directory compiles multiple times?为什么外部包含目录编译多次? 【发布时间】:2021-08-26 14:42:56 【问题描述】:

当我对我的代码进行更改时,外部文件会被编译多次。我正在使用数学库 glm,Visual Studio 似乎多次编译完全相同的 glm/vec3.hpp 文件。我已经多次包含glm header了,好像没有使用之前编译过的代码,而是重新编译了一遍。

例如,在我的 math.h 中我已经包含了。

#ifndef MATH_HH
#define MATH_HH

#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
...

当我在更改代码后进行编译时,我看到 Visual Studio 多次编译 glm/vec3.hpp。基本上它每次编译我编辑的文件之一时都会编译它。

例如,Visual Studio 输出如下所示:

1>C:\test\external\glm\glm\detail\type_vec3.hpp(50,1): warning C4201: nonstandard extension used: nameless struct/union
...
10>own_file.cc
11>C:\test\external\glm\glm\detail\type_vec3.hpp(50,1): warning C4201: nonstandard extension used: nameless struct/union
...

有没有办法防止这种情况发生?还是每次某些 cpp 文件使用它们时都需要编译它们?还是我只是对 Visual Studio 的样式警告感到困惑?

【问题讨论】:

GLM 项目中没有这样的文件。您能否提供提及此文件的实际构建输出?还是你的意思是glm/vec3.hpp 是的,我的意思是头文件。更新了问题以更详细地描述问题。 glm != glm-math 【参考方案1】:

基本上它每次编译我编辑的文件之一时都会编译它。

这就是 C++ 的工作原理。它编译源文件。包含头文件只是获取该文件中的文本并将其转储到源文件中。因此,如果在 3 个源文件中包含一个头文件,则该头文件的文本将被编译 3 次。

有预编译的头文件(编译器专用工具)和 C++20 模块功能可以避免这种情况。但除此之外,你无能为力。

【讨论】:

这样就搞定了,谢谢!等不及 C++20 成为标准了。 @Toothery:这已经是一个标准了。到目前为止,它还不常见,许多编译器还没有完全实现它。

以上是关于为啥外部包含目录编译多次?的主要内容,如果未能解决你的问题,请参考以下文章

修改 makefile 以包含外部编译的对象

vs2022为啥会在D盘根目录下生成windows kits文件?

如果我包含“-ansi”编译器选项,为啥我的 C++0x 代码无法编译?

为啥我的编译防护不能防止多个定义包含?

为啥编译器默认不自动添加或生成包含保护?

cmake的外部编译