Is there a way to disable pre-compiled headers (PCH) when building a plug-in?
We have a some C++ libraries we need to make part of our plug-in. We’d prefer not to add a specific header in each cpp file. Our standard is to always include the associated header file (hpp or h) first in the cpp to ensure that the header file has all the references it needs. We also keep the headers as lean as possible with minimal includes and forward declarations. This encourages good code hygiene - keeping the code clean and honest. It can also be faster especially for code with minimal dependencies.
The build system seems to look for the first included header and assume that is the PCH file. If all the cpp files in the plug-in do not include that header first then the following error is given during a build:
EXEC : error : All source files in module "MyPlugin" must include the same precompiled header first.
I dug around in the docs, and build code and couldn’t find anything to limit or disable precompiled headers during the build.
These commands and settings were the most related though they don’t quite seem to do it:
PCHUsage = PCHUsageMode.NoSharedPCHs;
MinFilesUsingPrecompiledHeaderOverride = 0; // or other larger numbers
Target.bForceIncludePrecompiledHeader = true;
// If this is set it seems to want to look in the Engine/Source folder. Specifying a file relative to this also doesn't seem to be sufficient.
SharedPCHHeaderFile = "";
Is there a way to set the compiler directive /Y- which turns off precompiled headers? I see AdditionalArguments used in some places in the build code though it doesn’t seem obvious how it might be set in a plug-in build.cs file.
We’ve added a common header file to be used as a PCH just to get things going for now though we have a few other C++ libraries that we will need to include in the plug-in and don’t look forward to making a “one header to rule them all” include arbitrarily at the beginning of each cpp file.
I intensely back the idea of speeding up build times - though I don’t think that PCH is a perfect “one size fits all” option.
Some alternatives that we’ve thought of:
Create by hand a grouped cpp file that starts with an include to a PCH file followed by all the other cpp files. Ideally we would hide or include as non-compiling the grouped cpp files from the GenerateProjectFiles.bat. Would PublicAdditionalShadowFiles be the best way to do this? It seems to only hide single files. Is there a way to hide a whole directory of cpp files? [Seems a lot of work to do something that the build system is already doing just to get around the issue.]
Put the C++ libraries that we need in Engine/Source/ThirdParty as static libraries - assuming that makes sense for a plug-in and PCH files aren’t auto-enabled there. [That may be a problem keeping the plug-in code all self-contained. The libraries will need to be used in related plug-ins - for example the editor and the runtime. Paper2D seems to use the technique of having the editor plug-ins depend on the runtime plug-in.]
We’d like to take advantage of the Unreal build system so that it should be easy to target all the platforms that Unreal supports.
Any suggestions or alternatives that we haven’t considered?
I put my compiled libraries plus headers in a folder in MyGame/Plugins/MyPlugin/ThirdParty and that works fine. No pch needed for the library, only for the plugin cold. Also, my plugin lives in my game (actually a test fixture for my plugin) folder so nothing in the Engine folder changes. Given how rapidly Epic is putting out UE4 versions, putting anything in the Engine hierarchy is a bad idea (IMHO).
Have you readthis wiki article? It focuses on games modules, but works for plugins as well.
Thanks for the suggestions - I have indeed seen that wiki article and assumed that Plug-ins are essentially a more restricted form of a module - this is what I had above as my second alternative.
I have been assuming that plug-ins would be at the Unreal Engine source level - just at a game/project level didn’t even occur to me. I wonder if this will be supported (or even the primary mechanism) that custom plug-ins from the marketplace are applied?
Likewise I wonder if I’d be able to associate a custom ThirdParty source folder with a marketplace plug-in? The full steps to package up a plug-in for the marketplace are still a work in progress. Would all the code for a marketplace plug-in have to be contained within a given plug-in’s folder?
[Would any Epic devs be able to confirm or elaborate?]
I’d like to ensure that our plug-in is organized correctly for eventual inclusion on the Unreal marketplace.
Wrap the libraries your plugins depend on in external modules, which means you build the libs (not UBT) and create a Build.cs to let UBT know what public include directories and libs your external module provides. Then you can link your libraries with your plugins simply by adding the appropriate module names into PrivateDependencyModuleNames in the Build.cs of your plugins and UBT will setup the appropriate include/lib paths. That way you can move your libraries around if need be without too much effort, you may need to update some paths[1] in the Build.cs for the external module(s) but no change will be required to the plugins themselves. This is how most of the Third Party libraries are setup, so there are plenty of examples, Vorbis is a pretty simple one.
[1] TIP: Build paths in the Build.cs from the module filename so they’ll still work without any changes if the module is relocated:
// path to directory containing this Build.cs file
var **basePath** **=** Path**.**GetDirectoryName(RulesCompiler**.**GetModuleFilename(**moduleName**));
[Cool idea about making the path relative to the module.]
I considered (and may still go) this route. I just have two concerns:
May lose out on not using UBT to maintain one build file for all UE4 targeted platforms. [Will have to build libs for each platform ourselves - though this may be a necessary evil since we will have to test things out anyway.]
Not sure if this will be supported in the packaging up process Epic will use for putting up plug-ins on the Unreal Marketplace.