2015-05-01 10:58:14 -04:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Threading ;
using System.Linq ;
using System.Reflection ;
using AutomationTool ;
using UnrealBuildTool ;
[Help("Builds a plugin, and packages it for distribution")]
2015-05-06 11:06:35 -04:00
[Help("Plugin", "Specify the path to the descriptor file for the plugin that should be packaged")]
[Help("NoHostPlatform", "Prevent compiling for the editor platform on the host")]
2015-05-01 15:01:10 -04:00
[Help("TargetPlatforms", "Specify a list of target platforms to build, separated by '+' characters (eg. -TargetPlatforms=Win32+Win64). Default is all the Rocket target platforms.")]
2015-05-06 11:07:47 -04:00
[Help("Package", "The path which the build artifacts should be packaged to, ready for distribution.")]
2015-05-01 10:58:14 -04:00
class BuildPlugin : BuildCommand
{
public override void ExecuteBuild ( )
{
// Get the plugin filename
string PluginFileName = ParseParamValue ( "Plugin" ) ;
if ( PluginFileName = = null )
{
throw new AutomationException ( "Plugin file name was not specified via the -plugin argument" ) ;
}
2015-05-06 11:06:35 -04:00
2015-05-01 10:58:14 -04:00
// Read the plugin
PluginDescriptor Plugin = PluginDescriptor . FromFile ( PluginFileName ) ;
// Clean the intermediate build directory
string IntermediateBuildDirectory = Path . Combine ( Path . GetDirectoryName ( PluginFileName ) , "Intermediate" , "Build" ) ;
if ( CommandUtils . DirectoryExists ( IntermediateBuildDirectory ) )
{
CommandUtils . DeleteDirectory ( IntermediateBuildDirectory ) ;
}
2015-05-05 18:52:17 -04:00
// Get any additional arguments from the commandline
string AdditionalArgs = "" ;
if ( ParseParam ( "Rocket" ) )
{
AdditionalArgs + = " -Rocket" ;
}
2015-05-01 15:01:10 -04:00
// Build the host platforms
2015-05-01 10:58:14 -04:00
List < string > ReceiptFileNames = new List < string > ( ) ;
UE4Build . BuildAgenda Agenda = new UE4Build . BuildAgenda ( ) ;
2015-05-01 15:01:10 -04:00
UnrealTargetPlatform HostPlatform = BuildHostPlatform . Current . Platform ;
if ( ! ParseParam ( "NoHostPlatform" ) )
{
2015-05-05 18:52:17 -04:00
AddPluginToAgenda ( Agenda , PluginFileName , Plugin , "UE4Editor" , TargetRules . TargetType . Editor , HostPlatform , UnrealTargetConfiguration . Development , ReceiptFileNames , AdditionalArgs ) ;
2015-05-01 15:01:10 -04:00
}
// Add the game targets
List < UnrealTargetPlatform > TargetPlatforms = Rocket . RocketBuild . GetTargetPlatforms ( this , HostPlatform ) ;
foreach ( UnrealTargetPlatform TargetPlatform in TargetPlatforms )
{
if ( Rocket . RocketBuild . IsCodeTargetPlatform ( HostPlatform , TargetPlatform ) )
{
2015-05-05 18:52:17 -04:00
AddPluginToAgenda ( Agenda , PluginFileName , Plugin , "UE4Game" , TargetRules . TargetType . Game , TargetPlatform , UnrealTargetConfiguration . Development , ReceiptFileNames , AdditionalArgs ) ;
AddPluginToAgenda ( Agenda , PluginFileName , Plugin , "UE4Game" , TargetRules . TargetType . Game , TargetPlatform , UnrealTargetConfiguration . Shipping , ReceiptFileNames , AdditionalArgs ) ;
2015-05-01 15:01:10 -04:00
}
}
// Build it
2015-05-01 10:58:14 -04:00
UE4Build Build = new UE4Build ( this ) ;
Build . Build ( Agenda , InDeleteBuildProducts : true , InUpdateVersionFiles : false ) ;
// Package the plugin to the output folder
string PackageDirectory = ParseParamValue ( "Package" ) ;
if ( PackageDirectory ! = null )
{
List < BuildProduct > BuildProducts = GetBuildProductsFromReceipts ( ReceiptFileNames ) ;
PackagePlugin ( PluginFileName , BuildProducts , PackageDirectory ) ;
}
}
2015-05-05 18:52:17 -04:00
static void AddPluginToAgenda ( UE4Build . BuildAgenda Agenda , string PluginFileName , PluginDescriptor Plugin , string TargetName , TargetRules . TargetType TargetType , UnrealTargetPlatform Platform , UnrealTargetConfiguration Configuration , List < string > ReceiptFileNames , string InAdditionalArgs )
2015-05-01 10:58:14 -04:00
{
// Find a list of modules that need to be built for this plugin
List < string > ModuleNames = new List < string > ( ) ;
foreach ( ModuleDescriptor Module in Plugin . Modules )
{
if ( Module . IsCompiledInConfiguration ( Platform , TargetType ) )
{
ModuleNames . Add ( Module . Name ) ;
}
}
// Add these modules to the build agenda
if ( ModuleNames . Count > 0 )
{
string Arguments = String . Format ( "-plugin {0}" , CommandUtils . MakePathSafeToUseWithCommandLine ( PluginFileName ) ) ;
foreach ( string ModuleName in ModuleNames )
{
Arguments + = String . Format ( " -module {0}" , ModuleName ) ;
}
string ReceiptFileName = BuildReceipt . GetDefaultPath ( Path . GetDirectoryName ( PluginFileName ) , TargetName , Platform , Configuration , "" ) ;
Arguments + = String . Format ( " -receipt {0}" , CommandUtils . MakePathSafeToUseWithCommandLine ( ReceiptFileName ) ) ;
ReceiptFileNames . Add ( ReceiptFileName ) ;
2015-05-05 18:52:17 -04:00
if ( ! String . IsNullOrEmpty ( InAdditionalArgs ) )
{
Arguments + = InAdditionalArgs ;
}
2015-05-01 10:58:14 -04:00
Agenda . AddTarget ( TargetName , Platform , Configuration , InAddArgs : Arguments ) ;
}
}
static List < BuildProduct > GetBuildProductsFromReceipts ( List < string > ReceiptFileNames )
{
List < BuildProduct > BuildProducts = new List < BuildProduct > ( ) ;
foreach ( string ReceiptFileName in ReceiptFileNames )
{
BuildReceipt Receipt = BuildReceipt . Read ( ReceiptFileName ) ;
BuildProducts . AddRange ( Receipt . BuildProducts ) ;
}
return BuildProducts ;
}
static void PackagePlugin ( string PluginFileName , List < BuildProduct > BuildProducts , string PackageDirectory )
{
// Clear the output directory
CommandUtils . DeleteDirectoryContents ( PackageDirectory ) ;
// Copy all the files to the output directory
List < string > MatchingFileNames = FilterPluginFiles ( PluginFileName , BuildProducts ) ;
foreach ( string MatchingFileName in MatchingFileNames )
{
string SourceFileName = Path . Combine ( Path . GetDirectoryName ( PluginFileName ) , MatchingFileName ) ;
string TargetFileName = Path . Combine ( PackageDirectory , MatchingFileName ) ;
CommandUtils . CopyFile ( SourceFileName , TargetFileName ) ;
2015-05-19 12:09:26 -04:00
CommandUtils . SetFileAttributes ( TargetFileName , ReadOnly : false ) ;
2015-05-01 10:58:14 -04:00
}
// Get the output plugin filename
string TargetPluginFileName = CommandUtils . MakeRerootedFilePath ( Path . GetFullPath ( PluginFileName ) , Path . GetDirectoryName ( Path . GetFullPath ( PluginFileName ) ) , PackageDirectory ) ;
PluginDescriptor NewDescriptor = PluginDescriptor . FromFile ( TargetPluginFileName ) ;
NewDescriptor . bEnabledByDefault = false ;
NewDescriptor . bInstalled = true ;
NewDescriptor . Save ( TargetPluginFileName ) ;
}
static List < string > FilterPluginFiles ( string PluginFileName , List < BuildProduct > BuildProducts )
{
string PluginDirectory = Path . GetDirectoryName ( PluginFileName ) ;
// Set up the default filter
FileFilter Filter = new FileFilter ( ) ;
Filter . AddRuleForFile ( PluginFileName , PluginDirectory , FileFilterType . Include ) ;
Filter . AddRuleForFiles ( BuildProducts . Select ( x = > x . Path ) , PluginDirectory , FileFilterType . Include ) ;
Filter . Include ( "/Resources/..." ) ;
Filter . Include ( "/Content/..." ) ;
Filter . Include ( "/Intermediate/Build/.../Inc/..." ) ;
Filter . Include ( "/Source/..." ) ;
// Add custom rules for each platform
string FilterFileName = Path . Combine ( Path . GetDirectoryName ( PluginFileName ) , "Config" , "FilterPlugin.ini" ) ;
if ( File . Exists ( FilterFileName ) )
{
Filter . ReadRulesFromFile ( FilterFileName , "FilterPlugin" ) ;
}
// Apply the standard exclusion rules
Filter . ExcludeConfidentialFolders ( ) ;
Filter . ExcludeConfidentialPlatforms ( ) ;
// Apply the filter to the plugin directory
return new List < string > ( Filter . ApplyToDirectory ( PluginDirectory , true ) ) ;
}
}