如何检查每个头文件是否包含必需的包含文件?

How to check each header file includes required include files?

本文关键字:文件 包含必 是否 包含 何检查 检查      更新时间:2023-10-16

我正在使用C++和cmake开发我的应用程序。

我想正确检查每个C++头文件包含所需的包含文件。

下面是一个示例:

A.马普

inline void func_a() {
}

B.马普

// #include "a.hpp" is missing
inline void func_b() {
func_a();
}

主.cpp

#include "a.hpp"
#include "b.hpp"
int main() {}

演示:https://wandbox.org/permlink/kZqoNHMYARIB3bc1

B.HPP应包括A.HPP。假设 b.hpp 缺失包括 a.hpp。如果 main.cpp 在 b.hpp 之前包含 a.hpp,则不会发生编译错误。如果包含顺序相反,则发生编译错误。

我想检查一下这种问题。

我正在 emacs 上使用飞行检查。它可以很好地检查此问题。我想在我的 cmake 构建系统中进行一些检查机制。

例如,如果我执行make depcheck,则检测到编译错误。

我认为如果我设置一个单独编译所有头文件但不链接的 cmake 目标,则会报告预期的编译错误。

到目前为止,我找不到如何设置它。

有什么办法可以做到这一点吗?还是其他实现目标的方法?

我的头文件包含策略

每个头文件都应包含包含所需元素的头文件。换句话说,每个头文件都应该单独编译。

我想要实现的目标

我想知道通过工具辅助自动检测 b.hpp 的方法缺少"#include"a.hpp"。该工具意味着不是编辑器。我想cmake可以做到这一点。我正在努力寻找方法。

传统智慧是将源文件添加到每个标头。即使b.cpp只包含以下行:

include "b.hpp" // Note, this should be the first include

这样,您可以独立编译每个 cpp 文件,成功编译意味着相应的标头是独立的。

当然,如果您已经有一个实现文件,那么首先移动要包含的相应标头可以确保这一点。

@StoryTeller 的答案

传统智慧是将源文件添加到每个标头。

是实现目标的适当方式。它需要添加许多源文件。这是烦人的工作,尤其是我开发了一个仅标题库。

如何自动化该过程?

我找到了一种方法来检查cmake上缺少的包含文件。策略是单独和直接编译每个头文件。

这是CMakeList.txt

cmake_minimum_required(VERSION 3.8.2)
project(test_checker)
add_custom_target(chkdeps)
file(GLOB HDR_ROOT "*.hpp")
FOREACH (HDR ${HDR_ROOT})
message(STATUS "${HDR}")
get_filename_component(HDR_WE ${HDR} NAME_WE)
SET(CHK_TARGET "${HDR_WE}.chk")
add_custom_target(
${CHK_TARGET}
COMMAND ${CMAKE_CXX_COMPILER} -c ${HDR}
VERBATIM
)
add_dependencies(chkdeps ${CHK_TARGET})
ENDFOREACH ()

要检查缺少的包含文件,请执行make chkdeps

为了只做编译,我使用add_custom_target。自定义目标名称为chkdeps(检查依赖项(。这是所有头文件依赖项检查的目标。

我使用file(GLOB HDR_ROOT "*.hpp")获得 *.hpp 的列表。对于每个得到的文件,我添加自定义目标,仅用于使用 add_custom_target 进行编译。

我添加扩展.chk以避免冲突。例如,如果文件名为a.hpp则目标名称为a.chk

我使用-c选项执行命令${CMAKE_CXX_COMPILER}-c选项仅用于编译。我只在Linux上测试了cmake。我知道直接设置编译选项不利于跨平台开发。CMAKE 可能提供仅编译跨平台机制。但到目前为止,我找不到它。

然后,我使用 add_dependencies 将依赖项添加到chkdeps。由于这种依赖性,当我执行make chkdeps时,所有自定义目标(a.chkb.chk(都会运行。

当我运行make chkdeps时,我收到预期的错误"'func_a'未在此范围内声明",如下所示。

make chkdeps                                                                                                                                                    
Built target a.chk
/home/kondo/work/tmp/fly_check/b.hpp: In function 'void func_b()':
/home/kondo/work/tmp/fly_check/b.hpp:3:5: error: 'func_a' was not declared in this scope; did you mean 'func_b'?
3 |     func_a();
|     ^~~~~~
|     func_b
make[3]: *** [CMakeFiles/b.chk.dir/build.make:57: CMakeFiles/b.chk] Error 1
make[2]: *** [CMakeFiles/Makefile2:78: CMakeFiles/b.chk.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:113: CMakeFiles/chkdeps.dir/rule] Error 2
make: *** [Makefile:131: chkdeps] Error 2