Plugin Package With No Source Code - Issue

Summary

There is a one particular use case that fails when attempting to create a UE Plugin without source code. If the project including the plugin is a C++ project, then a “Clean”/”Build” or “Rebuild” (which does a “Clean”) will fail. The reason it fails is the “Clean” will remove files that are needed during the link but are not rebuilt.

Detail / Documentation

Attached is a zip file of 3 UE projects:

1. MyNoSourcePluginDev (which is the sample project where the target plugin is developed – the development project needs the source code).

2. MyTestBP (which is a test of the no source plugin in the context of a BP only client project)

3. MyTestCPP (which is a test of the no source plugin in the context of C++ client project – this is where it fails).

MyNoSourcePluginDev – is a simple (no code) c++ project with a minimal custom plugin. Included in the project is a script that will package the plugin for deployment to clients. The packaging will use the UE plugin packager, delete the Source/Private directory to remove the source code leaving the Source/Public directory for BP accessible resources, and zip the plugin for deployment. The deployment zip file can be found in <root>/Saved/PluginPackages/MyPlugNoSource/MyPluginNoSourcePackage.zip

MyTestBP – is a simple BP only UE project where the no source Plugin is unzipped and referenced. Using the ‘no source plugin’ and Packaging the resulting project has no issues.

MyTestCPP – is a simple C++ UE Project where the ‘no source Plugin’ is unzipped and referenced. If you open the solution generated by this project using “GenerateVisualStudioProjectFiles” you can successfully “Build” this project. That is, the unzipped ‘no source plugin’ has included all the necessary files to link this project. However, if you do a “Clean” / “Build” or “Rebuild”, files included in the no source plugin are deleted and the build (and subsequent builds) will fail. Note that the MyPluginNoSource.uplugin includes “Precompiled”: true and the Source/MyPluginNoSource/MyPluginNoSource.Build.cs includes “bUsePrecompiled = true;”. These directives are NOT included in the project where the plugin is being developed but are forced into the packaged build of the plugin.

It seems that the “Precompiled”: true directive is not being honored when the makefile is being generated. The ‘Clean’ target in that makefile should not touch the ‘intermediate’ or ‘binary’ directories laid down by that plugin.

Steps to Reproduce

  1. Unzip the attached zip
  2. GenerateVisualStudioProjectFiles for project MyNoSourcePluginDev.
  3. Open/Rebuild project MyNoSourcePluginDev. This is a simple sample of a plugin being developed.
  4. At the root of MyNoSourcePluginDev there is a script PackagePlugin.bat that will package the plugin under Saved/PluginPackages and zip it. At the top of that script is a Var that points to the Unreal Engine root. Please edit that script to point to your 5.6 UE install. Run that script.
  5. Unzip the resulting MyPluginNoSourcePackage.zip into the ‘Plugins’ directory of MyTestBP and MyTestCpp projects (included in the attached zip). These are examples of BP only and C++ client project that uses this ‘no source plugin’. Note that the Source/Private (source code) is intentionally missing from the plugin. Also note that the uplugin file for the plugin contains “Precompiled”: true and the Build.cs file has the bUsePrecompiled=true directive.
  6. Run ‘GenerateVisualStudioProjectFiles’ on the project MyTestCPP.
  7. Open the project MyTestCPP.sln. Do a “Build” (not “Rebuild”) to demonstrate that the ‘no source plugin’ can be build successfully - it included everything that is necessary.
  8. Then do a “Rebuild”. This will fail because the implied ‘Clean’ will delete files in the ‘no source plugin’ needed for the link phase of MyTestCPP - these are files that cannot be regenerated without the source. The makefile that is generated by UBT should exclude this plugin from the ‘Clean’ target.

Hi Greg,

This case is unsupported. The workaround is to put the packaged plugin under the Engine as if it was installed through Fab. The proper location is Engine\Plugins\Marketplace. You might have to create the Marketplace folder if plugins have not been installed yet. This works are the official distribution contains a “flag” that prevents the Engine artefacts from being cleaned.

In the case where the user is not using the precompiled Engine, there is no way to distribute a “sourceless” precompiled plugin as you are doing it right now. The workaround is to create a precompiled wrapper lib that contains the secret code and call that lib API from the plugin code.

Regards,

Martin

Hi Martin,

Thanks for the reply.

Just so I understand… you are supporting a ‘sourceless’ precompiled plugin only if its installed to the engine. If source is include then it could be installed to project.

Forgive me, but I’m having trouble understanding the distinction. My use case seems entirely valid. I have a set of ‘internal’ plugins that are internal to my application. I distribute them to partners that extend them per my specifications. I don’t want these partners to have the source code. I also don’t want to require pieces of my application to be installed to the engine every where it gets deployed. I want to install these plugins to a project.

When you say its ‘unsupported’, is that UE Policy? It seems to me that it is very close to being supported. As I demonstrated in the zip I sent, the ‘sourceless’ plugin works in all cases except ‘rebuild’ and its specifically because the ‘Clean’ target is not respecting the ‘Precompiled’ flag. This would be relatively easy to fix. Can I offer to fix it for you?

Hi Greg,

This is not a frequent workflow amongst our licensees so it was not deemed important enough to implement. Another reason is that plugins are compiled “against” a specific engine version so it makes sense that they go in the engine folder when precompiled. Plugins must be recompiled with every major release (5.4, 5.5, 5.6...) but are compatible through the hotfixes for a given release (5.6.x) . If the licensee is working with the engine source, he could be making changes to the public API which could invalidate plugins that are pre-compiled against our official sources. This case could result in runtime problems at the editor level and compile\link issues for the runtime.

Those are the main reasons why we don’t support sourceless plugins in a project or when a licensee is compiling custom exes.

It is possible to submit Pull Requests on our GitHub repo. All requests are evaluated by the owner of the modified feature. https://dev.epicgames.com/documentation/en\-us/unreal\-engine/contributing\-to\-the\-unreal\-engine

Regards,

Martin

I understand your reasoning and I think its reasonable for UE to have a policy that would disallow plugins that it distributes to require source code - for the reasons you specify - those plugins need to be rebuilt as the engine changes. For plugins which you allow to distributed on you marketplace it makes perfect sense. However, ‘requiring source code for marketplace plugins’ and ‘supporting sourceless plugins in a UE project’ are 2 very different things. You can enforce the former without disallowing the latter.

This does not mean that a sourceless plugin has no place in a customer project. It absolutely does as I stated above. I am developing plugins which I do not plan to distribute except internally and I have full control of those distributions including what engine is required. Expecting my customers to install my plugins to their engine everywhere my application deployed is unreasonable - I’m sure you see that. Consider the versioning issue I’ll have going forward. These plugins I’m developing correlate to my application’s versions much more closely than to the engine version.

I get it that resources are finite and this has a low priority - this is why I offered to do the heavy lifting. Thanks anyway for your time.