[UE4]Precompile Plugins - Build from Installed Engine
Keywords: UE4, Building Multiple Plugins, Dependencies, Without Source, Source Removed, Prebuilding, Precompile, Distributing
If want to distribute plugins with source removed using installed engine (in EpicGames Launcher), do steps as shown in following content.
Related References
[UE4]Precompile Plugins - Build from Engine Source
GUI
1, New two plugins (Edit -> Plugins -> New Plugin) that named as P1
and P2
.
2, Add source for P1
and P2
.
We have assumed that Actor1
was in plugin P1
, and Actor2
was in plugin P2
, P2
has dependencies on P1
, but P1
has no dependencies on P2
.
Actor1.h
#include "Actor1.h"
#include "Engine.h"
// Sets default values
AActor1::AActor1()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AActor1::BeginPlay()
{
Super::BeginPlay();
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString("Actor1 BeginPlay"));
}
Actor2.h
#include "Actor2.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
#include "Actor1.h"
// Sets default values
AActor2::AActor2()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AActor2::BeginPlay()
{
Super::BeginPlay();
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString("Actor2 BeginPlay"));
FTransform Trans;
AActor1 A1 = GetWorld()->SpawnActor<AActor1>(AActor1::StaticClass(), Trans);
}
3, List P1
in PrivateDependencyModuleNames
of Build.cs
of P2
:
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"P1"
// ... add private dependencies that you statically link with here ...
}
);
4, List plugin P1
in P2.uplugin
, then add WhitelistPlatforms
in P1.uplugin
and P2.uplugin
:
P1.uplugin
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "P1",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "P1",
"Type": "Runtime",
"LoadingPhase": "Default",
"WhitelistPlatforms": [
"Win64"
]
}
]
}
P2.uplugin
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "P2",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "P2",
"Type": "Runtime",
"LoadingPhase": "Default",
"WhitelistPlatforms": [
"Win64"
]
}
],
"Plugins": [
{
"Name": "P1",
"Enabled": true
}
]
}
5, Close editor, rebuild project source and start editor.
6, Package plugin P1
: Edit -> Plugins -> Project -> P1
-> Package
then close editor and remove TestTD\Plugins\P1
, then copy packaged version of P1
into engine plugins directory.
then you can remove private source files:
When restart editor, you will see the packaged plugin P1
in Installed
tab of plugins.
Attention:
Packaging project would fail if haven’t packaged plugin.
Following message is the error if haven’t packaged plugin:
UATHelper: Packaging (Windows (64-bit)): ERROR: Missing precompiled manifest for 'TestPlugin'. This module was most likely not flagged for being included in a precompiled build - set 'PrecompileForTargets = PrecompileTargetsType.Any;' in TestPlugin.build.cs to override.
PackagingResults: Error: Missing precompiled manifest for 'TestPlugin'. This module was most likely not flagged for being included in a precompiled build - set 'PrecompileForTargets = PrecompileTargetsType.Any;' in TestPlugin.build.cs to override.
7, Package plugin P2
: Edit -> Plugins -> Project -> P2
-> Package:
then close editor and remove TestTD\Plugins\P2
, then copy packaged version of P2
into engine plugins directory.
then you can remove private source files:
8, List P2
in PublicDependencyModuleNames
of TestTD.Build.cs
:
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class TestTD : ModuleRules
{
public TestTD(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "NavigationSystem", "AIModule" });
PublicDependencyModuleNames.AddRange(new string[] { "P2" });
}
}
9, List P1
and P2
in TestTD.uproject
{
"FileVersion": 3,
"EngineAssociation": "4.24",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "TestTD",
"Type": "Runtime",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "P1",
"Enabled": true
},
{
"Name": "P2",
"Enabled": true
}
]
}
Otherwise you would get error at building:
The game module `TestTD` could not be loaded. There may be an operating system error or the module may not be properly set up.
9, Now you can inlcude plugin P2
headers in your game project:
#include "TestTDGameMode.h"
#include "TestTDPlayerController.h"
#include "TestTDCharacter.h"
#include "UObject/ConstructorHelpers.h"
#include "Actor2.h"
ATestTDGameMode::ATestTDGameMode()
{
// use our custom PlayerController class
PlayerControllerClass = ATestTDPlayerController::StaticClass();
// set default pawn class to our Blueprinted character
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/TopDownCPP/Blueprints/TopDownCharacter"));
if (PlayerPawnBPClass.Class != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Class;
}
}
void ATestTDGameMode::StartPlay()
{
Super::StartPlay();
FTransform Trans;
AActor2* Pawn = GetWorld()->SpawnActor<AActor2>(AActor2::StaticClass(), Trans);
}
then rebuild project source and start editor, now you can package project:
File -> Package Project -> Windows -> Win64.
CLI
Command:
"D:\Epic Games\UE_4.24\Engine\Binaries\DotNET\AutomationTool.exe" BuildPlugin -Plugin=E:/TestTD/Plugins/MyPlugin/MyPlugin.uplugin -Package=F:/Build/MyPlugin -CreateSubFolder
Source file of BuildPlugin
command :
Engine\Source\Programs\AutomationTool\Scripts\BuildPluginCommand.Automation.cs
References
How to package C++ plugin without private source code (only binaries + headers) in 4.20?
https://forums.unrealengine.com/development-discussion/engine-source-github/1521453-how-to-package-c-plugin-without-private-source-code-only-binaries-headers-in-4-20
If a man is to shed the light of the sun upon other men, he must first of all have it within himself. ― Romain Rolland