The Gradle recommended conventions for “private” header files is to place them in the cpp directory next to their implementation files. When I do this, I get unexpected behavior which is dependent on the header file extension (i.e. .h, .hpp) and is incorrect in all cases.
.hpp: When a header file ending in .hpp is placed in the cpp directory, it is included on the g++ command line as if it were a .cpp file. Dependening on the order in which this file appears on the command line can effect the contents of the resulting object file. To reproduce this, create a cpp file with a single function (not a class, just a function). Declare the function in a .hpp file and consume it in a test program. Invoke g++ manually and play with the order in which the .cpp and .hpp are listed on the command line.
.h: When a header file ending in .h is placed in the cpp directory, it is included on the g++ command line as if it were a .cpp file. This results in a precompiled header being generated. This is not necessarily a desired behavior and can result.
In all these cases, it seems the problems would go away if the header files were not included on the command line except when part of a -I flag. While a workaround may be to explicitly exclude *.h, *.hpp from the source set, this seems clumsy. Rather, for the relatively rare case where you want to compile your header file, making the necessary source set adjustments seems appropriate.