Writing module with headers next to source files

I try to encapsulate in a module a set of c++ classes (.cpp and .h) that I share with some other projects.
The special convention of putting headers in a Public folder and source in a Private folder is really constraining in my case for a few reasons:

  • The structure of classes put in a hierarchy of directories should be replicated in the Public folder.
  • My other projects would have to inherit from that constraint which would break their standard coding guidelines.
  • Having .h and .cpp together is rather standard and allows more logical #include “classname.h” convention.
  • For each include I would always have to put a full path even if they would normally be in the same directory.

I tried already if I could:

  • Put all the code in the Public folder but my understanding is that sources (.cpp) should stay in Private.
  • Duplicate headers in Public and keeping them also next to source for the other projects (but that’s a bad practice and we should avoid code file duplication).
  • Have headers in Public that are just including their Private header counter part. But this fails also when headers include other headers.

A possible solution could be that Public include files could still search in the Private include path, but I couldn’t find a way to get the module Build.cs to achieve that.

Is there no way to avoid putting headers in a separate Public folder so that my non UE projects wouldn’t inherit that constraint if I want to share the code without duplicating files? I wish I could just put one header in Public with a list of all headers to place public but then I get errors when those include refers to other includes.
Any solution would be welcome.

I think you over thinking too much, let me explain the difference:

Public is the code that you would want to distribute to create linking to without exposing the source, practically only header files

Private is the the code you don’t want to expose.

Engine has this division so it is not require to have a source to code for UE4 just by providing public directories with header files and provide only headers that are needed for this. UBT also wont create externs on Private directory to speed up linking process, as in assumes headers in Private would not be linkble.

But there no obligation for you to follow this pattern (maybe except if you plan to make a plugin for marketplace, there might be requirement to follow it, then it can’t be helped).

So no, cpp files don’t need to be in Private, also if you don’t plan for anyone to link to your module you don’t need Public at all

In fact, look on C++ game project, module it create don’t have that division at all, it automatically puts everything to Private assuming linking to game module will never be needed at all, because it usally does not or else you make multiple modules which most people are not even aware about modules.

Now about those points:

-The structure of classes put in a hierarchy of directories should be replicated in the Public folder.

There no requirement for that, in fact there many cases of that in engine, bah Actor class code for example is sperate in to multiple cpp files. The only reason why you need header files is to paste (because thats what include does) decleration of used classes, the structure in no even put in to account to it. in linking process linker will find target function code regardless. Same goes with cpp code, there no path location put in to account in compilation, for linker they don’t exist so there is no requirement to replicate directory structure on both.

-My other projects would have to inherit from that constraint which would break their standard coding guidelines.

If you speak about non-UE projects, they to need use those conventions there either, look on third party folder wan what engine is using, ton of libraries that have different conventions, both in code and path structure. again same as above, for compiler it makes no difference. To begin with you non-UE should go thru Third Party workflow, not main UBT workflow, they should not be part of them module, third party library inclusion tutorials shows how to do it.

-Having .h and .cpp together is rather standard and allows more logical #include “classname.h” convention.

-For each include I would always have to put a full path even if they would normally be in the same directory."

UBT automatically sets include path for both Public and Private directory and Public for external modules, you should not use full path at all. If you need to do it then there something wrong, because you should not need put full path at all.

Thank you for taking the time to answer. I really appreciate.
I will just try to be concise and explain why this is not yet solving my issue.

  • The purpose of Public and Private is quite clear to me and thank you to sum it up.
  • I tried to copy all .h and .cpp from Private to Public and it failed compiling (have to check again precise error). So I deduced .cpp should stay in private folder. Maybe I came to a wrong conclusion? But anyway, putting all in Public is certainly not recommended.
  • In my case I still need my headers to be Public to reference them in other module or game logic so I can’t put all in Private.
  • I understand the hierarchy of directories is not mandatory but that was the way I wanted to keep it organized (classes, derived classes, grouped by different modules). I didn’t want to break that structure because I had to share those files (headers and cpp) in an Unreal module.
  • I also had prefer keeping header and source next to each other because files were naturally structured like that for my other projects and this is quite common. Also for example vs extension TabsStudio I’m using only groups by default .h and .cpp that are in the same directory (but found out luckily there is an option if that’s not the case).
  • True that third party code could go in a different private folder, but here I still wanted to expose my classes in public headers and use them in gameplay code to avoid encapsulating each class in a new UE class. I understand it would be better to design each public class as a clean UE class but this would be clearly too much work at least while prototyping with my module. Also if I design each class will UE convention, then they can’t be shared anymore with my other non UE project. […]

[…] This is why I had wished to keep my hierarchy structure with .h and .cpp next to each other in the Private folder and then in Public just put another header file including the headers in Private folder that I wanted to put public. But I found no way to achieve that. I don’t want to take too much of your time but wanted to clarify my request here. In the meantime I reorganized my two projects so that they both search for .h in a Public folder and .cpp in a Private folder and be compatible with Unreal rules. That is not ideal for me but in the end the best working solution I could find.