Knowledge Base: Workaround for Circular Dependencies

Article written by Branden T.
During development, you may encounter an error while building, such as:
UnrealBuildTool : error : Circular dependency on ModuleA.Build.cs detected.

Full Route: Target -> ModuleA.Build.cs …


In the example above both modules are private dependencies of each other.

From what I have been taught a “Private” dependency is a include that is only in a cpp file(s). Since cpp file are and or should not be included into other files how can a Private Dependency ever be circular? This is one of the main motivations for using forward declarations in the headers so using #includes can be done as much as possible in the cpp files. I do not see how a private dependency can ever be circular, can you explain?

Sometimes you can find yourself in a situation where you have classes from different modules that need to reference each other…
Class A in Module A, references Class A from Module B that has a Class B that needs to reference Class B from Module A.
Forward declarations solve circular inclusion of .h files within the same module, but if those are separate modules, they need to reference each other in their Build.cs files, which results in circularity, “CircularlyReferencedDependentModules” addresses this issue.
Of course this isn’t the “best practice”, and a more SOLID approach would be, to make a 3rd module that references modules A and B, and within it, create child classes that would serve as abstractions for the actual A and B classes from modules A and B, and implement the methods that inter-reference these classes inside the children, effectively making the A and B modules agnostic.
But that requires a more complex design, which can be an over-engineered solution for something that could have been simple.
However, sometimes the “simple solution” can result in a lot of wasted time that will eventually force you to refactor a lot of code.