Title: How to check each header file includes required include files?
Tags: c++;cmake;dependencies;include
Question: I'm developing my application using C++ and cmake.

I'd like to check each C++ header file includes required include files correctly.

Here is an example:

a.hpp

```inline void func_a() {
}
```

b.hpp

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

main.cpp

```#include "a.hpp"
#include "b.hpp"

int main() {}
```

Demo: https://wandbox.org/permlink/kZqoNHMYARIB3bc1

b.hpp should include a.hpp. Let's say b.hpp missing include a.hpp. If main.cpp include a.hpp before b.hpp, no compile error is occurred. If include order is opposite, compile error is occurred.

I'd like to check this kind of problem.

I'm using fly-check on emacs. It checks this problem well. I'd like to some checking mechanism into my cmake build system.

For example, if I execute ```make depcheck```, then compile error is detected.

I think that if I setup a cmake target that compiles all header files individually but not link, the expected compile error would be reported.

I couldn't find how to setup that, so far.

Is there any way to do that? Or other ways to achieve the goal ?

my header file inclusion policy

Each header file should include header files that contain required element. In other words, each header file should compile individually.

What I want to achieve

I want to know the way to automatically detect b.hpp is missing `#include "a.hpp" by tool assist. The tool means not editor. I guess that cmake could do that. I'm trying to find the way.

Comment: try https://include-what-you-use.org/

Comment: @AlanBirtles, thank you. I will check it.

Comment: @VTT, I guess that fly-check compiles currently opened file directly on background. It doesn't compile from main.cpp. So it can detect func_a() is jessepalmer@example.com.

Comment: @RobertAndrzejuk, My goal is how to check missing include file. Not what is the best inclusion rule.

Comment: related: https://stackoverflow.com/q/3644293/4770166 https://stackoverflow.com/q/41214159/4770166

Comment: *"I'm using fly-check on emacs. It checks this problem well."* - are you sure that it does? How does it deal with problem of indirect includes (when `b.hpp` includes `c.hpp` that includes `a.hpp`) and with problem of private includes (when `a.hpp` must not be included directly and `c.hpp` must be included instead)?

Comment: Possible duplicate of [Google C++ Style Guide include order](https://stackoverflow.com/questions/54347804/google-c-style-guide-include-order)

Here is the accepted answer: @StoryTeller 's answer 

```
  Conventional wisdom is to add source files to every header.
```

is appropriate way to achieve the goal. It requires adding many source files. It is annoying work especially I develop a header only library. 

How to automate that process? 

I found a way to check missing include file on cmake. The strategy is compile each header files individually and directly.

Here is CMakeLists.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 ()
```

To check missing include files, execute ```make chkdeps```.

In order to do only compile, I use add_custom_target. The custom target name is ```chkdeps``` (check dependencies). This is the target for all header files dependency checking.

I get the list of *.hpp using ```file(GLOB HDR_ROOT "*.hpp")```. For each got files, I add custom target for only compile using add_custom_target. 

I add the extension ```.chk``` to avoid conflict. For example if the file name is ```a.hpp``` then the target name is ```a.chk```.

I execute the COMMAND ```${CMAKE_CXX_COMPILER}``` with ```-c``` option. The ```-c``` option is for only compile. I only tested the cmake on Linux. I know setting compile option directly is not good for cross platform development. cmake might provides compile only cross platform mechanism. But I couldn't find it, so far.

Then I add dependency to ```chkdeps``` using add_dependencies. Due to this dependency, when I execute ```make chkdeps```, all custom targets (```a.chk``` and ```b.chk```) run.

When I run ```make chkdeps```, then I got the expected error "'func_a' was not declared in this scope" as follows.

```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
```


Here is another answer: Conventional wisdom is to add source files to every header. Even if ```b.cpp``` includes only this line:

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

That way, you can compile every cpp file in isolation, and a successful compilation means the corresponding header is self-contained.

Of course, if you have an implementation file already, then moving the corresponding header to be included first goes towards ensuring that.

Comment for this answer: @VTT - One can find chinks in the armor of every method. It's still conventional wisdom that works for non-pathological cases.
Comment for this answer: @StoryTeller, thank you for the answer. But I'm looking for a way that automatically find these kind of missing inclusion. Even if main.cpp successfully compiled by accident.
Comment for this answer: I believe this is what naïve include checkers do. Successful compilation does not actually mean that file includes necessary include files, for example lack of config include or lack of include of some template specialization will cause compilation to yield incorrect result so the header checked is not actually self-contained.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 2, 'CommentCount': 7, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2019:00:09/11/19', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<c++><cmake><dependencies><include>', 'Title': 'How to check each header file includes required include files?', 'ViewCount': 1290, 'id': 57885042, 'user_AboutMe': '', 'user_AccountId': 2170681.0, 'user_DisplayName': 'Takatoshi Kondo', 'user_Reputation': 2913.0, 'user_Views': 449.0, 'user_id': 1922763.0}}