Custom generated.cpp file support

Hi,
I’ve recently been working on implementing a scripting system into UE4. It’s going alright. But I notice from both my own experience and that of others that any system that needs to, at compile time, generate binding code via UHT’s IScriptGeneratorPluginInterface doesn’t really have anywhere that they can put said code and have it compile, on its own, separate from whatever’s included in the project. For example, SkookumScript has to generate a massive .inl file that is then included into another compilation unit.

I already know from looking at the code of UBT and UHT about “generated.cpp” files. For those who don’t, any file in the generated folder named following the wildcard “[ModuleName].generated*.cpp”. However, with UHT and UBT as they are, these aren’t any use to me. UHT will, via some code written to remove any excess files that may not be needed, inadventently remove all of the custom compilation units I generate. The only way to prevent this is to change UHT. As well as this, UHT won’t generate any debug symbols for generated.cpp files, and the only way to turn this on is, again, by changing the code of UHT. This itself could be avoided if UBT supported a custom type of generated.cpp file that is not part of the normal generated code - as it is now, I know very well that I am using an exploit.

What I’m requesting is this: allow me a way to somehow create my own generated.cpp files in the Intermediate folder and have UBT compile them, with or without debugging symbols. Without this feature I am left with no alternative to either injecting massive amounts of code into a single, predefined compilation unit somewhere in the project (and fight with the same issue of the bindings being too large to compile as before), generating inline files individually (One for each module + some modules have to be split due to, again, hundreds of classes) and expecting the user to create empty .cpp files to include them in, or, as I have done, modifying UHT.

Here are some examples of what I mean:


Generated bindings. The custom compilation unit here is LuaRuntime.generated.cpp. It works but when I change any aspect of the owning project it has to recompile due to…

This code from UnrealHeaderTool. Understandably, it’s not at all designed for the presence of anything other than files matching the format "..cpp", rather than targeting “.of.cpp" as it does in my modification. This means that every time UHT runs on a game module, any bindings have to recompile. And, as it is, bindings take a looong time to compile, a problem that would be very much compounded by only having to compile them once. Having to compile a binding for the ENTIRE engine module every time I change something in my game means an extra minute of compiling every time I change my game, and I won’t ever get anything done with that going on.
On the topic of the format of generated header files:


UBT won’t compile any generated.cpp file - only those that match the FileWildcard stored here. The FileWildcard, as I have explained, is "[ModuleName].generated.cpp” and this means that, for example, I cannot generate a file called “LuaBindings.generated.cpp” and have it compile as part of the LuaRuntime module. I am making use of a convenient bug in the current functionality by, as I did above, by titling my file “LuaRuntime.[BoundModuleName].generated.cpp”. I would much prefer to have a bit more freedom over the name.*

I understand that this is a niche feature but it would be very quick to implement. I also understand that such a feature would need to be well thought out and not have security implications; perhaps it might be a good idea to require for custom generated compilation units to be turned on or individually specified. If it turns out that the Epic Games staff would actually accept such a feature I would even be willing to create my own pull request for it - as it will, in the long run, make my LuaJIT binder plugin much easier for people to use when I release its source.

We had a discussion about this internally… I can see the value for ease of implementation in doing that, but it breaks the encapsulation that a plugin is supposed to have, and wouldn’t work well for binary distributions of the engine where all the engine modules are precompiled. The main reason for wanting to support scripting languages is to provide a higher-level alternative to C++, and I think a precompiled build of the editor is a particularly important use case to consider.

I don’t have any particularly compelling alternatives to suggest off hand. If it’s an interpreted language, the ideal scenario would be to have the parser reference the reflected UE4 types, and just thunk into functions as appropriate from the VM (effectively what Blueprints do). If it’s a statically compiled language, you probably want some other mechanism for linking/configuring things against the UE4 module system anyway, so it seems reasonable not to assume a 1:1 mapping with C++ modules.