Build System IncludePathsModuleNames and DependencyModuleNames documentation clarification

I need serious clarification of the documentation around the lists of modules and dependencies, includes, etc. It’s quite confusing and the documentation is a little short for newcomers who still don’t know how Unreal build system works, even after reading the docs available, and I guess it’s even more frustrating for people new to c++, unlike me.

In a build.cs file you have to fill several lists, but people seem to do it using every module they think they would need without really understanding what’s going on. I’ve done that too but now I’m having serious include problems and I need to understand this for good:


First about these two:

*PublicIncludePathModuleNames (List<String>)
List of modules names (no path needed) with header files that our module’s public headers needs access to, but we don’t need to “import” or link against.

PrivateIncludePathModuleNames (List<String>)
List of modules name (no path needed) with header files that our module’s private code files needs access to, but we don’t need to “import” or link against.*

Question 1 ) “*don’t need to “import” or link against” *This doesn’t make sense, I asked other c++ developers with no Unreal knowledge, and they were confused too. What would I want to do with the module but import or link against? What should I include here then?

Question 2) Why does it say “public headers” and “private code” on each. This is very subtle but important. Does it mean cpp should be private and headers public in my plugin, for example? (I’m sure this is not the case because you can put any file anywhere you want and I’ve seen it everywhere).

Question 3 ) Should a module be added to both lists if I use it in the public and private files?


And now about these two:

*PublicDependencyModuleNames (List<String>)
List of public dependency module names (no path needed) (automatically does the private/public include). These are modules that are required by our public source files.

PrivateDependencyModuleNames (List<String>)
List of private dependency module names. These are modules that our private code depends on but nothing in our public include files depend on.*

Question 4 ) These are “dependency” and the others “includePath”. Include means headers, I understand. What are these then? What does it mean with “dependency” in Unreal terms?. Wouldn’t I want to use them by including them?

Question 5 ) The private list doc text doesn’t mention “no path needed” and “automatically does the private/public include”. Should I take it into account from the other similar list ( in that case, it should be mentioned and I’ll notify that to them ) or it doesn’t?.

Question 6 ) Why does it say “does the private/public include”?. If you add a module to the public list, then all private and public exposed funcionality is available? Shouldn’t private content be hidden?. What does it mean by “include”? Wasn’t it just dependencies?


Question 7 ) So In my case, I have a plugin with two modules. Both have several files in subfolders inside public and private/ folders, and more subfolders.
If I want module A to use module B, I put the header files that A will need from B in it’s public folder.
So I need to include ModuleA in which variable? Include? Dependency? both? public or private? I suppose private shouldn’t be accesed so I’m forced to put all headers to be accesed public, right?.

After I understand all this, I’ll probably write it down clearly for everybody in a wiki page.

  1. If you just want access to some header-only types (think template libraries for example), then you need the include paths set but don’t need to link. So you add the module here instead of Public/PrivateDependencyModuleNames, since the latter creates a hard dependency. This use case is rare in UE4. However, you would also use these when you have dynamic dependencies - a lot of the editor modules in particular expose an interface that lets you use the functionality without static linking. In these cases, you add the module name to one of these two lists, and also to the DynamicallyLoadedModuleNames list.

  2. Cpp files should always be in Private. Headers can be either Public or Private; they go in Public if other modules may need to include them, otherwise if they’re internal only, put them in Private. Note that headers in your Public folder should never include headers from the Private folder.

  3. Not 100% sure, but I suspect adding a module to the Public list also implicitly makes it accessible from Private code. I don’t recall ever needing to add the same entry to both lists.

  4. These lists are basically stronger versions - modules in these implicitly have their include paths added, but they are also made statically linked dependencies. If you want to directly use the types they expose (other than interfaces and header-only types), then they need to go in these lists and not the IncludePath lists. So in most cases you’ll be using these.

  5. I assume “no path needed” means when you add an entry to the list, you add the name only. In that case, yeah that applies to all the lists. The “automatically does the private/public include” doesn’t make much sense to me. But basically, by adding a dependency, it is also setting up the include paths; but to the module’s Public headers only. This is exactly the same for the Private list; by choosing the Private list, you’re basically saying that you will only include headers from this module within your own Private code, therefore the dependency/include paths don’t need to be propagated to other modules which may add your module to their lists. Yeah, it’s confusing.

  6. See above. Yeah, Private is never exposed.

  7. Yes, put them somewhere within B’s Public folder. You most likely want direct access to the types, in which case you need a static dependency. So you add “ModuleB” to the Public/PrivateDependencyModuleNames list of ModuleA. Always prefer Private by default to reduce propagating dependencies. But if you know you’ll need to include some of B’s headers from within some of A’s Public headers, then the dependency should be Public; otherwise, when someone else comes to add a dependency on A, they may hit include errors. Of course, if you don’t ever intend for anyone to have a dependency on A, then it doesn’t need to even have a Public folder, and you can always use the Private lists in its Build.cs file.

1 Like

Thanks a lot for your time, @kamrann . I know this was a long post.

  1. “In these cases, you add the module name to one of these two lists, and also to the DynamicallyLoadedModuleNames list.” ← Ugh. This is not clear at all in the docs. I never imagined this was the reason. So I understand these two are not very often used, right?

  2. “headers in your Public folder should never include headers from the Private folder.” ← Ouch. Really?: Then I’ll have to move every header to public… I think this is why I have that compile error then.

  3. “also implicitly makes it accessible from Private code”.<-- OK, great!.. seems right. Needs testing then. ANYBODY KNOWS?

  4. “dependency/include paths don’t need to be propagated to other modules which may add your module to their lists. Yeah, it’s confusing.” ← Oh… Maybe that’s the reason. Definitely needs a better explanation. Do you know if there’s any wiki page already about this? I think we have to write a longer documentation for the build file, at least for these lists.

  5. “it doesn’t need to even have a Public folder, and you can always use the Private lists in its Build.cs file”. Oh. That’s a good one. I don’t think anybody will need the editor module at all. Good!

​​​​​​​Thanks a lot. it’s clearer now.