I have a project with a CMakeLists.txt at the root, and two directories: src and test. src builds a library, and test builds an executable testing the library.
In src, when I define access levels for sources, I’d like to make some .h private to the normal users of the library, but visible to the unit tests. How to do that ?
I’ve solved a similar situation by creating an interface library which brings in the normal one and additionally “publishes” the private path. Something like this:
Do “normal users” exist in the project or with your project embedded in theirs? Or are “normal users” importing installed targets? In the latter case, CMake does have ways to expose properties differently in the build tree and in exports using generator expressions.
If all of the consumers have access to the build tree, though, that doesn’t help you, and a separate clearly named INTERFACE target makes sense, as previously suggested.
It seems to me that you are asking the wrong question. I’ve found that the process of unit testing frequently informs design (what is exposed; what is not). Your unit testing should be “black-box” testing (without relying on implementation details that, by definition should be subject to change).
Note that if any of your public headers include any of your private headers, you have to deliver them and your interface is exposed. Hyrum’s law applies.
If you really want to test internal implementations that are not exposed, I would create a private OBJECT library and run your unit tests against that, then link the private library into your exposed library. This is logically equivalent to the interface library suggested previously (and the interface may be superior, depending on your purpose) but the implementation-details library that you unit test explicitly captures your requirements in a straightforward way.