2015-09-01 12:27:21 -04:00
|
|
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
#include "BlueprintNativeCodeGenPCH.h"
|
|
|
|
|
#include "NativeCodeGenCommandlineParams.h"
|
2015-09-09 18:51:40 -04:00
|
|
|
#include "BlueprintNativeCodeGenManifest.h"
|
2015-09-01 12:27:21 -04:00
|
|
|
|
2015-09-04 13:35:03 -04:00
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogNativeCodeGenCommandline, Log, All);
|
2015-09-01 12:27:21 -04:00
|
|
|
|
|
|
|
|
/** */
|
|
|
|
|
const FString FNativeCodeGenCommandlineParams::HelpMessage = TEXT("\n\
|
|
|
|
|
\n\
|
|
|
|
|
-------------------------------------------------------------------------------\n\
|
2015-09-24 18:57:23 -04:00
|
|
|
:: GenerateNativePluginFromBlueprint :: Converts Blueprint assets into C++ \n\
|
2015-09-01 12:27:21 -04:00
|
|
|
-------------------------------------------------------------------------------\n\
|
|
|
|
|
\n\
|
|
|
|
|
:: \n\
|
|
|
|
|
:: Usage \n\
|
|
|
|
|
:: \n\
|
|
|
|
|
\n\
|
2015-09-24 18:57:23 -04:00
|
|
|
UE4Editor.exe <project> -run=GenerateNativePluginFromBlueprint [parameters]\n\
|
2015-09-01 12:27:21 -04:00
|
|
|
\n\
|
|
|
|
|
:: \n\
|
2015-09-04 13:35:03 -04:00
|
|
|
:: Parameters \n\
|
2015-09-01 12:27:21 -04:00
|
|
|
:: \n\
|
|
|
|
|
\n\
|
2015-09-04 13:35:03 -04:00
|
|
|
-whitelist=<Assets> Identifies assets that you wish to convert. <Assets> \n\
|
|
|
|
|
can be a comma seperated list, specifying multiple \n\
|
|
|
|
|
packages (either directories, or explicit assets) in \n\
|
|
|
|
|
the form: /Game/MyContentDir,/Engine/EngineAssetName. \n\
|
2015-09-01 12:27:21 -04:00
|
|
|
\n\
|
2015-09-04 13:35:03 -04:00
|
|
|
-blacklist=<Assets> Explicitly specifies assets that you don't want \n\
|
2015-09-24 18:57:23 -04:00
|
|
|
converted (listed in the same manner as the -whitelist \n\
|
|
|
|
|
param). This takes priority over the whitelist (even if\n\
|
|
|
|
|
it results in uncompilable code). \n\
|
2015-09-01 12:27:21 -04:00
|
|
|
\n\
|
2015-09-24 18:57:23 -04:00
|
|
|
-output=<TargetDir> Specifies the path where you want converted assets \n\
|
2015-09-04 13:35:03 -04:00
|
|
|
saved to. If left unset, this will default to the \n\
|
|
|
|
|
project's intermeadiate folder (within a sub-folder of \n\
|
|
|
|
|
its own). If specified as a relative path, it will be \n\
|
2015-09-24 18:57:23 -04:00
|
|
|
interpreted as relative to the project directory. \n\
|
2015-09-18 14:01:11 -04:00
|
|
|
\n\
|
2015-09-24 18:57:23 -04:00
|
|
|
-pluginName=<Name> Defines the generated plugin's name. If the output \n\
|
|
|
|
|
directory doesn't match this in name, then a sub-folder\n\
|
|
|
|
|
will be created there to house the plugin. \n\
|
2015-09-09 18:51:40 -04:00
|
|
|
\n\
|
2015-09-24 18:57:23 -04:00
|
|
|
-noWipe By default, we'll clear out the target directory from \n\
|
|
|
|
|
previous conversions. However, with this, if the \n\
|
|
|
|
|
target directory contains source from a previous run, \n\
|
|
|
|
|
we'll build atop the existing module and appends to its\n\
|
|
|
|
|
existing manifest. \n\
|
2015-09-09 18:51:40 -04:00
|
|
|
\n\
|
2015-09-24 18:57:23 -04:00
|
|
|
-manifest=<Path> Specifies where to save the resultant manifest file. If\n\
|
|
|
|
|
<Path> is not an existing directory or file, then it is\n\
|
|
|
|
|
assumed that this is a file path. If a manifest already\n\
|
|
|
|
|
exists here, then it'll be used to define the target \n\
|
|
|
|
|
output directory (which will be read from the existing \n\
|
|
|
|
|
manifest file). If left unset then the manifest will \n\
|
|
|
|
|
default to the plugin's directory. \n\
|
2015-09-18 14:01:11 -04:00
|
|
|
\n\
|
2015-09-24 18:57:23 -04:00
|
|
|
-preview When specified, the process will NOT wipe any existing \n\
|
|
|
|
|
files, and the target assets will NOT be compiled and \n\
|
|
|
|
|
converted. Instead, just a manifest file will be \n\
|
|
|
|
|
generated, detailing the command's predicted output. \n\
|
2015-09-01 12:27:21 -04:00
|
|
|
\n\
|
|
|
|
|
-help, -h, -? Display this message and then exit. \n\
|
|
|
|
|
\n");
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
* NativeCodeGenCommandlineParamsImpl
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
namespace NativeCodeGenCommandlineParamsImpl
|
|
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
static const FString DefaultPluginName(TEXT("GeneratedBpCode"));
|
2015-09-04 13:35:03 -04:00
|
|
|
static const FString ParamListDelim(TEXT(","));
|
2015-09-24 18:57:23 -04:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cleans up the passed in path from the commandline (removes quotes,
|
|
|
|
|
* corrects slashes, etc.), so that it is ready to be utilized by the
|
|
|
|
|
* conversion process.
|
|
|
|
|
*
|
|
|
|
|
* @param PathInOut The path you want standardized.
|
|
|
|
|
*/
|
|
|
|
|
static void SanitizePathParam(FString& PathInOut);
|
2015-09-01 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|
2015-09-24 18:57:23 -04:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
static void NativeCodeGenCommandlineParamsImpl::SanitizePathParam(FString& PathInOut)
|
|
|
|
|
{
|
|
|
|
|
PathInOut.RemoveFromStart(TEXT("\""));
|
|
|
|
|
PathInOut.RemoveFromEnd(TEXT("\""));
|
|
|
|
|
FPaths::NormalizeDirectoryName(PathInOut);
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-01 12:27:21 -04:00
|
|
|
/*******************************************************************************
|
|
|
|
|
* FNativeCodeGenCommandlineParams
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
FNativeCodeGenCommandlineParams::FNativeCodeGenCommandlineParams(const TArray<FString>& CommandlineSwitches)
|
|
|
|
|
: bHelpRequested(false)
|
2015-09-24 18:57:23 -04:00
|
|
|
, bWipeRequested(true)
|
2015-09-18 14:01:11 -04:00
|
|
|
, bPreviewRequested(false)
|
2015-09-01 12:27:21 -04:00
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
using namespace NativeCodeGenCommandlineParamsImpl;
|
|
|
|
|
|
2015-09-04 13:35:03 -04:00
|
|
|
IFileManager& FileManager = IFileManager::Get();
|
|
|
|
|
|
2015-09-01 12:27:21 -04:00
|
|
|
for (const FString& Param : CommandlineSwitches)
|
|
|
|
|
{
|
|
|
|
|
FString Switch = Param, Value;
|
|
|
|
|
Param.Split(TEXT("="), &Switch, &Value);
|
|
|
|
|
|
|
|
|
|
if (!Switch.Compare(TEXT("h"), ESearchCase::IgnoreCase) ||
|
|
|
|
|
!Switch.Compare(TEXT("?"), ESearchCase::IgnoreCase) ||
|
|
|
|
|
!Switch.Compare(TEXT("help"), ESearchCase::IgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
bHelpRequested = true;
|
|
|
|
|
}
|
2015-09-04 13:35:03 -04:00
|
|
|
else if (!Switch.Compare(TEXT("whitelist"), ESearchCase::IgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
Value.ParseIntoArray(WhiteListedAssetPaths, *NativeCodeGenCommandlineParamsImpl::ParamListDelim);
|
|
|
|
|
}
|
|
|
|
|
else if (!Switch.Compare(TEXT("blacklist"), ESearchCase::IgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
Value.ParseIntoArray(BlackListedAssetPaths, *NativeCodeGenCommandlineParamsImpl::ParamListDelim);
|
|
|
|
|
}
|
|
|
|
|
else if (!Switch.Compare(TEXT("output"), ESearchCase::IgnoreCase))
|
|
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
SanitizePathParam(Value);
|
2015-09-04 13:35:03 -04:00
|
|
|
// if it's a relative path, let's have it relative to the game
|
|
|
|
|
// directory (not the UE executable)
|
2015-09-09 18:51:40 -04:00
|
|
|
if (FPaths::IsRelative(Value))
|
2015-09-04 13:35:03 -04:00
|
|
|
{
|
|
|
|
|
Value = FPaths::Combine(*FPaths::GameDir(), *Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FileManager.DirectoryExists(*Value) || FileManager.MakeDirectory(*Value))
|
|
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
OutputDir = Value;
|
2015-09-04 13:35:03 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
UE_LOG(LogNativeCodeGenCommandline, Warning, TEXT("'%s' doesn't appear to be a valid output directory, reverting to the default."), *Value);
|
2015-09-09 18:51:40 -04:00
|
|
|
}
|
|
|
|
|
}
|
2015-09-24 18:57:23 -04:00
|
|
|
else if (!Switch.Compare(TEXT("pluginName"), ESearchCase::IgnoreCase))
|
2015-09-22 14:06:00 -04:00
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
PluginName = Value;
|
2015-09-22 14:06:00 -04:00
|
|
|
}
|
2015-09-24 18:57:23 -04:00
|
|
|
else if (!Switch.Compare(TEXT("noWipe"), ESearchCase::IgnoreCase))
|
2015-09-09 18:51:40 -04:00
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
bWipeRequested = false;
|
2015-09-09 18:51:40 -04:00
|
|
|
}
|
2015-09-18 14:01:11 -04:00
|
|
|
else if (!Switch.Compare(TEXT("preview"), ESearchCase::IgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
bPreviewRequested = true;
|
|
|
|
|
}
|
2015-09-09 18:51:40 -04:00
|
|
|
else if (!Switch.Compare(TEXT("manifest"), ESearchCase::IgnoreCase))
|
|
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
SanitizePathParam(Value);
|
2015-09-09 18:51:40 -04:00
|
|
|
|
|
|
|
|
if (FileManager.FileExists(*Value))
|
|
|
|
|
{
|
|
|
|
|
ManifestFilePath = Value;
|
|
|
|
|
}
|
|
|
|
|
else if (FileManager.DirectoryExists(*Value))
|
|
|
|
|
{
|
|
|
|
|
ManifestFilePath = FPaths::Combine(*Value, *FBlueprintNativeCodeGenManifest::GetDefaultFilename());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LogNativeCodeGenCommandline, Display, TEXT("Unsure if '%s' is supposed to denote a directory or a filename, assuming it's a file."), *Value);
|
|
|
|
|
|
|
|
|
|
FString FilePath = FPaths::GetPath(*Value);
|
|
|
|
|
if (FileManager.DirectoryExists(*FilePath) || FileManager.MakeDirectory(*FilePath))
|
|
|
|
|
{
|
|
|
|
|
ManifestFilePath = Value;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (FPaths::IsRelative(Value))
|
|
|
|
|
{
|
|
|
|
|
Value = FPaths::ConvertRelativePathToFull(Value);
|
|
|
|
|
}
|
2015-09-24 18:57:23 -04:00
|
|
|
UE_LOG( LogNativeCodeGenCommandline, Warning, TEXT("'%s' doesn't appear to be a valid manifest file name/path, defaulting to: '%s'."),
|
|
|
|
|
*Value, *FBlueprintNativeCodeGenManifest::GetDefaultFilename() );
|
2015-09-09 18:51:40 -04:00
|
|
|
}
|
2015-09-04 13:35:03 -04:00
|
|
|
}
|
|
|
|
|
}
|
2015-09-01 12:27:21 -04:00
|
|
|
else
|
|
|
|
|
{
|
2015-09-04 13:35:03 -04:00
|
|
|
//UE_LOG(LogNativeCodeGenCommandline, Warning, TEXT("Unrecognized commandline parameter: %s"), *Switch);
|
2015-09-01 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
}
|
2015-09-09 18:51:40 -04:00
|
|
|
|
|
|
|
|
bool const bUtilizeExistingManifest = !ManifestFilePath.IsEmpty() && !bWipeRequested && FileManager.FileExists(*ManifestFilePath);
|
2015-09-24 18:57:23 -04:00
|
|
|
// an existing manifest would specify where to put the plugin
|
2015-09-22 14:06:00 -04:00
|
|
|
if (!bUtilizeExistingManifest)
|
2015-09-09 18:51:40 -04:00
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
if (PluginName.IsEmpty())
|
2015-09-22 14:06:00 -04:00
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
PluginName = NativeCodeGenCommandlineParamsImpl::DefaultPluginName;
|
2015-09-22 14:06:00 -04:00
|
|
|
}
|
2015-09-24 18:57:23 -04:00
|
|
|
if (OutputDir.IsEmpty())
|
2015-09-22 14:06:00 -04:00
|
|
|
{
|
2015-09-24 18:57:23 -04:00
|
|
|
const FString DefaultOutputPath = FPaths::Combine(*FPaths::Combine(*FPaths::GameIntermediateDir(), TEXT("Plugins")), *PluginName);
|
|
|
|
|
OutputDir = DefaultOutputPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( PluginName.Compare(FPaths::GetBaseFilename(OutputDir)) )
|
|
|
|
|
{
|
|
|
|
|
OutputDir = FPaths::Combine(*OutputDir, *PluginName);
|
2015-09-22 14:06:00 -04:00
|
|
|
}
|
|
|
|
|
}
|
2015-09-01 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|