Build tool sometimes puts a cpp file in the wrong module? [4.11+]

I’m guessing something changed in the UE build chain after 4.10? (since the version of VS2015 used is the same across the board)

Everything generates Intermediate\Build\Win64\UE4Editor\Development/DebugGame[pluginname]\Module.[pluginname].number.cpp files when compiling my plugin. Usually there’s one more for 4.10, but those always compile fine, unlike 4.11 and 4.12 after I added a new directory with some source code to my solution.

There, unlike with 4.10, I’ve had a (#pragma once’d or not doesn’t matter) file A that only gets included in file B get split off from that file, so 1_of_2.cpp has an #include “fileAonlyusedinB.cpp” and 2_of_2.cpp has an #include “fileBthatneedsA.cpp”… which leads to this maddening group of messages:

2>Module.HammUEr.2_of_2.cpp.obj : error LNK2005: "int __cdecl imin(int,int)" (?imin@@YAHHH@Z) already defined in Module.HammUEr.1_of_2.cpp.obj
2>Module.HammUEr.2_of_2.cpp.obj : error LNK2005: "void __cdecl linearize(unsigned char *,unsigned char const *,int)" (?linearize@@YAXPEAEPEBEH@Z) already defined in Module.HammUEr.1_of_2.cpp.obj
etc

The only way I’ve found of “fixing” this is to rename one of my code directories from MAPtype2 to ZMAPtype2 so it ends up in the second file and fileBthatneedsA.cpp gets bumped up to the first one, which leads to it compiling fine, but this isn’t really a workable solution.

Added weirdness is that doing the directory rename also kicks C.cpp - which uses D.cpp which is included in 2_of_2 - down to 1_of_2, but for some reason, this split is fine and doesn’t raise any flags.
Maybe because this time it’s the includer and not the includee that’s in 1_of_2 while the other file is in 2_of_2?

Hey turfster-

Based on my understanding, it sounds as though you have two classes in your plugin and when you compile each class is trying to include the other? Can you clarify if this is the case or if I am misunderstanding? Additionally, can you provide steps for me to follow to reproduce the issue locally?

I have many classes in my plugin, spread across 48 cpp/h combinations.
One of these is a_dxt, which only #includes my plugin-wide PCH.h (which is basically empty except for engine files). a_dxt is only #included in one of my other classes, STextureWidget.

The plugin used to compile fine. Yesterday, I pulled in more self-contained functionality code containing 13 cpp/h combos (none of which have anything to do with the 2 files already mentioned) in a subdirectory called MAPType2.

Now, under 4.10, compiling the plugin still goes off without a hitch. Under 4.11 and 4.12, however, during the build stage, it complains that the the functions exposed in a_dxt “are already defined in Module 1_of_2” near the end of the compilation process.

The reason for this seems to be that during build time, the subsets of user-created cpp files are split across various Module files… and unlike in 4.10, a_dxt and STextureWidget are not kept together in the same Module file, but end up in different files… and I get the “already defined” errors when it’s working on the other file.

If I rename the directory MAPType2 to ZMAPType2, it gets shifted to Module 2_of_2 while STextureWidget ends up in 1_of_2… and everything compiles without errors. Of course, while this workaround works, having to watch where files end up and moving them by renaming them is… very much not ideal.

I don’t really know how to reproduce this easily, besides just “having lots of source files split across various directories.”

I have not been able to reproduce this on my end. You mentioned pulling in “self-contained functionality code”. From what I’ve been able to find in relation to the LNK2005 error you reported, it sounds as though something in this new code has the same name/declaration as something in one of the other files. If possible, could you provide the plugin you’re using that is not compiling properly for me to investigate directly?

I got the plugin from the forums and added it to a project. I did not get the same errors you reported when I compiled in 4.11, however I did get a number of “class/struct type redefinition” errors. I also noticed one case of class FClassName: public TSharedFromThis which is somewhat confusing. To me that reads as “this class inherits from itself” which I wouldn’t think would compile. Is there a reason for this specific syntax?

Additionally, I found that adding UCLASS() and USTRUCT() to the different classes/structs in HammUErSettings.h cleared many of the redefinition errors. Can you let me know if these changes help or give different error warnings?

I… never got class/struct type redefinition errors (and neither did the marketplace people when it went through compile testing). I tried the DoesntCompile zip on another fresh 4.11 install on another machine, and it doesn’t compile there either…

The TSharedFromThis is straight from the codebase (notice the 255 engine files that define certain classes in exactly the same way) for working with SListViews

Hey turfster-

I’m not sure what may have changed in how the plugins are read by the editor. I have entered a bug report (UE-30530) to investigate why the plugin is not compiling in 4.11.

Cheers

Doug Wilson