You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
461 lines
16 KiB
C#
461 lines
16 KiB
C#
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.IO;
|
|
|
|
namespace UnrealBuildTool
|
|
{
|
|
/// <summary>
|
|
/// Represents a folder within the master project (e.g. Visual Studio solution)
|
|
/// </summary>
|
|
public class QMakefileFolder : MasterProjectFolder
|
|
{
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
public QMakefileFolder( ProjectFileGenerator InitOwnerProjectFileGenerator, string InitFolderName )
|
|
: base(InitOwnerProjectFileGenerator, InitFolderName)
|
|
{
|
|
}
|
|
}
|
|
|
|
public class QMakefileProjectFile : ProjectFile
|
|
{
|
|
public QMakefileProjectFile( string InitFilePath )
|
|
: base(InitFilePath)
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// QMakefile project file generator implementation
|
|
/// </summary>
|
|
public class QMakefileGenerator : ProjectFileGenerator
|
|
{
|
|
/// File extension for project files we'll be generating (e.g. ".vcxproj")
|
|
override public string ProjectFileExtension
|
|
{
|
|
get
|
|
{
|
|
return ".pro";
|
|
}
|
|
}
|
|
|
|
protected override bool WriteMasterProjectFile( ProjectFile UBTProject )
|
|
{
|
|
bool bSuccess = true;
|
|
return bSuccess;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the definition text into macro name and value (if any).
|
|
/// </summary>
|
|
/// <param name="Definition">Definition text</param>
|
|
/// <param name="Key">Out: The definition name</param>
|
|
/// <param name="Value">Out: The definition value or null if it has none</param>
|
|
/// <returns>Pair representing macro name and value.</returns>
|
|
private void SplitDefinitionAndValue(string Definition, out String Key, out String Value)
|
|
{
|
|
int EqualsIndex = Definition.IndexOf('=');
|
|
if (EqualsIndex >= 0)
|
|
{
|
|
Key = Definition.Substring(0, EqualsIndex);
|
|
Value = Definition.Substring(EqualsIndex + 1);
|
|
}
|
|
else
|
|
{
|
|
Key = Definition;
|
|
Value = "";
|
|
}
|
|
}
|
|
|
|
/// Adds the include directory to the list, after converting it to relative to UE4 root
|
|
private void AddIncludeDirectory(ref List<string> IncludeDirectories, string IncludeDir, string ProjectDir)
|
|
{
|
|
string FullProjectPath = Path.GetFullPath(ProjectFileGenerator.MasterProjectRelativePath);
|
|
string FullPath = "";
|
|
if (IncludeDir.StartsWith("/") && !IncludeDir.StartsWith(FullProjectPath))
|
|
{
|
|
// Full path to a fulder outside of project
|
|
FullPath = IncludeDir;
|
|
}
|
|
else
|
|
{
|
|
FullPath = Path.GetFullPath(Path.Combine(ProjectDir, IncludeDir));
|
|
FullPath = Utils.MakePathRelativeTo(FullPath, FullProjectPath);
|
|
FullPath = FullPath.TrimEnd('/');
|
|
}
|
|
|
|
if (!IncludeDirectories.Contains(FullPath) && !FullPath.Contains("FortniteGame/")) // @todo: skipping Fortnite header paths to shorten clang command line for building UE4XcodeHelper
|
|
{
|
|
IncludeDirectories.Add(FullPath);
|
|
}
|
|
}
|
|
|
|
// For later when moving all this back to MakefileGenerator.cs
|
|
private void AddDefines( ref List<string> DefinesContent, string define, string value)
|
|
{
|
|
}
|
|
|
|
private bool WriteQMakePro()
|
|
{
|
|
// Some more stuff borrowed from Mac side of things.
|
|
List<string> IncludeDirectories = new List<string>();
|
|
List<string> SystemIncludeDirectories = new List<string>();
|
|
List<string> DefinesAndValues = new List<string> ();
|
|
|
|
// DefineList.Add ("");
|
|
|
|
var QMakeIncludesFileName = MasterProjectName + "Includes.pri";
|
|
var QMakeIncludesPriFileContent = new StringBuilder();
|
|
|
|
var QMakeDefinesFileName = MasterProjectName + "Defines.pri";
|
|
var QMakeDefinesPriFileContent = new StringBuilder ();
|
|
|
|
string GameProjectPath = "";
|
|
string GameProjectFile = "";
|
|
string GameProjectRootPath = "";
|
|
|
|
string BuildCommand = "";
|
|
|
|
string QMakeGameProjectFile = "";
|
|
|
|
foreach (var CurProject in GeneratedProjectFiles) {
|
|
|
|
QMakefileProjectFile QMakeProject = CurProject as QMakefileProjectFile;
|
|
if (QMakeProject == null)
|
|
{
|
|
System.Console.WriteLine ("QMakeProject == null");
|
|
continue;
|
|
}
|
|
|
|
foreach (var CurPath in QMakeProject.IntelliSenseIncludeSearchPaths) {
|
|
AddIncludeDirectory(ref IncludeDirectories, CurPath, Path.GetDirectoryName(QMakeProject.ProjectFilePath));
|
|
// System.Console.WriteLine ("Not empty now? CurPath == ", CurPath);
|
|
}
|
|
foreach (var CurPath in QMakeProject.IntelliSenseSystemIncludeSearchPaths) {
|
|
AddIncludeDirectory (ref SystemIncludeDirectories, CurPath, Path.GetDirectoryName (QMakeProject.ProjectFilePath));
|
|
}
|
|
|
|
}
|
|
|
|
// Iterate through all the defines for the projects that are generated by
|
|
// UnrealBuildTool.exe
|
|
// !RAKE: move to seperate function
|
|
QMakeDefinesPriFileContent.Append("DEFINES += \\\n");
|
|
foreach (var CurProject in GeneratedProjectFiles)
|
|
{
|
|
QMakefileProjectFile QMakeProject = CurProject as QMakefileProjectFile;
|
|
if (QMakeProject == null)
|
|
{
|
|
System.Console.WriteLine ("QMakeProject == null");
|
|
continue;
|
|
}
|
|
|
|
foreach (var CurDefine in QMakeProject.IntelliSensePreprocessorDefinitions)
|
|
{
|
|
String define = "";
|
|
String value = "";
|
|
|
|
SplitDefinitionAndValue (CurDefine, out define, out value);
|
|
|
|
if(!DefinesAndValues.Contains(define))
|
|
{
|
|
// System.Console.WriteLine (CurDefine);
|
|
if (string.IsNullOrEmpty (value))
|
|
{
|
|
DefinesAndValues.Add ("\t");
|
|
DefinesAndValues.Add (String.Format("{0}=", define));
|
|
DefinesAndValues.Add (" \\\n");
|
|
}
|
|
else
|
|
{
|
|
DefinesAndValues.Add ("\t");
|
|
DefinesAndValues.Add (define);
|
|
DefinesAndValues.Add ("=");
|
|
DefinesAndValues.Add (value);
|
|
DefinesAndValues.Add (" \\\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var Def in DefinesAndValues) {
|
|
QMakeDefinesPriFileContent.Append (Def);
|
|
}
|
|
|
|
// Iterate through all the include paths that
|
|
// UnrealBuildTool.exe generates
|
|
// !RAKE: Move to seperate function
|
|
QMakeIncludesPriFileContent.Append ("INCLUDEPATH += \\\n");
|
|
foreach (var CurPath in IncludeDirectories) {
|
|
QMakeIncludesPriFileContent.Append ("\t");
|
|
QMakeIncludesPriFileContent.Append (CurPath);
|
|
QMakeIncludesPriFileContent.Append (" \\\n");
|
|
}
|
|
|
|
foreach (var CurPath in SystemIncludeDirectories) {
|
|
QMakeIncludesPriFileContent.Append ("\t");
|
|
QMakeIncludesPriFileContent.Append (CurPath);
|
|
QMakeIncludesPriFileContent.Append (" \\\n");
|
|
}
|
|
QMakeIncludesPriFileContent.Append("\n");
|
|
|
|
if (!String.IsNullOrEmpty (GameProjectName))
|
|
{
|
|
GameProjectPath = UnrealBuildTool.GetUProjectPath ();
|
|
GameProjectFile = UnrealBuildTool.GetUProjectFile ();
|
|
QMakeGameProjectFile = "gameProjectFile=" + GameProjectFile + "\n";
|
|
BuildCommand = "build=mono $$unrealRootPath/Engine/Binaries/DotNET/UnrealBuildTool.exe\n\n";
|
|
}
|
|
else
|
|
{
|
|
BuildCommand = "build=bash $$unrealRootPath/Engine/Build/BatchFiles/Linux/Build.sh\n";
|
|
}
|
|
|
|
var UnrealRootPath = Path.GetFullPath(ProjectFileGenerator.RootRelativePath);
|
|
|
|
var FileName = MasterProjectName + ".pro";
|
|
|
|
var QMakeSourcePriFileName = MasterProjectName + "Source.pri";
|
|
var QMakeHeaderPriFileName = MasterProjectName + "Header.pri";
|
|
var QMakeConfigPriFileName = MasterProjectName + "Config.pri";
|
|
|
|
var QMakeFileContent = new StringBuilder();
|
|
|
|
var QMakeSourcePriFileContent = new StringBuilder();
|
|
var QMakeHeaderPriFileContent = new StringBuilder();
|
|
var QMakeConfigPriFileContent = new StringBuilder();
|
|
|
|
var QMakeSectionEnd = " \n\n";
|
|
|
|
var QMakeSourceFilesList = "SOURCES += \\ \n";
|
|
var QMakeHeaderFilesList = "HEADERS += \\ \n";
|
|
var QMakeConfigFilesList = "OTHER_FILES += \\ \n";
|
|
var QMakeTargetList = "QMAKE_EXTRA_TARGETS += \\ \n";
|
|
|
|
if (!String.IsNullOrEmpty (GameProjectName)) {
|
|
GameProjectRootPath = GameProjectName + "RootPath=" + GameProjectPath + "\n\n";
|
|
}
|
|
|
|
QMakeFileContent.Append(
|
|
"# UnrealEngine.pro generated by QMakefileGenerator.cs\n" +
|
|
"# *DO NOT EDIT*\n\n" +
|
|
"TEMPLATE = aux\n" +
|
|
"CONFIG -= console\n" +
|
|
"CONFIG -= app_bundle\n" +
|
|
"CONFIG -= qt\n\n" +
|
|
"TARGET = UE4 \n\n" +
|
|
"unrealRootPath=" + UnrealRootPath + "\n" +
|
|
GameProjectRootPath +
|
|
QMakeGameProjectFile +
|
|
BuildCommand +
|
|
"args=$(ARGS)\n\n" +
|
|
"include(" + QMakeSourcePriFileName + ")\n" +
|
|
"include(" + QMakeHeaderPriFileName + ")\n" +
|
|
"include(" + QMakeConfigPriFileName + ")\n" +
|
|
"include(" + QMakeIncludesFileName + ")\n" +
|
|
"include(" + QMakeDefinesFileName + ")\n\n"
|
|
);
|
|
|
|
// Create SourceFiles, HeaderFiles, and ConfigFiles sections.
|
|
var AllModuleFiles = DiscoverModules();
|
|
foreach (string CurModuleFile in AllModuleFiles)
|
|
{
|
|
var FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile, ExcludeNoRedistFiles: bExcludeNoRedistFiles);
|
|
foreach (string CurSourceFile in FoundFiles)
|
|
{
|
|
string SourceFileRelativeToRoot = Utils.MakePathRelativeTo(CurSourceFile, Path.Combine(EngineRelativePath));
|
|
// Exclude Windows, Mac, and iOS only files/folders.
|
|
// This got ugly quick.
|
|
if (!SourceFileRelativeToRoot.Contains ("Source/ThirdParty/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/Windows/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/Mac/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/IOS/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/iOS/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/VisualStudioSourceCodeAccess/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/XCodeSourceCodeAccess/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/WmfMedia/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/IOSDeviceProfileSelector/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/WindowsDeviceProfileSelector/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/WindowsMoviePlayer/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/AppleMoviePlayer/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/MacGraphicsSwitching/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/Apple/") &&
|
|
!SourceFileRelativeToRoot.Contains ("/WinRT/")
|
|
)
|
|
{
|
|
if (SourceFileRelativeToRoot.EndsWith (".cpp"))
|
|
{
|
|
if (!SourceFileRelativeToRoot.StartsWith ("..") && !Path.IsPathRooted (SourceFileRelativeToRoot))
|
|
{
|
|
// SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
|
|
QMakeSourceFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
|
|
}
|
|
else
|
|
{
|
|
if (String.IsNullOrEmpty (GameProjectName))
|
|
{
|
|
// SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
|
|
QMakeSourceFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring (3) + "\" \\\n");
|
|
}
|
|
else if (!String.IsNullOrEmpty (GameProjectName))
|
|
{
|
|
QMakeSourceFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo (CurSourceFile, GameProjectPath) + "\" \\\n");
|
|
}
|
|
else
|
|
{
|
|
System.Console.WriteLine ("Error!, you should not be here.");
|
|
}
|
|
}
|
|
}
|
|
if (SourceFileRelativeToRoot.EndsWith (".h"))
|
|
{
|
|
if (!SourceFileRelativeToRoot.StartsWith ("..") && !Path.IsPathRooted (SourceFileRelativeToRoot))
|
|
{
|
|
// SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
|
|
QMakeHeaderFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
|
|
}
|
|
else
|
|
{
|
|
if (String.IsNullOrEmpty (GameProjectName))
|
|
{
|
|
// SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
|
|
QMakeHeaderFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring (3) + "\" \\\n");
|
|
}
|
|
else if (!String.IsNullOrEmpty (GameProjectName))
|
|
{
|
|
QMakeHeaderFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo (CurSourceFile, GameProjectPath) + "\" \\\n");
|
|
}
|
|
else
|
|
{
|
|
System.Console.WriteLine ("Error!, you should not be here.");
|
|
}
|
|
}
|
|
}
|
|
if (SourceFileRelativeToRoot.EndsWith (".cs"))
|
|
{
|
|
if (!SourceFileRelativeToRoot.StartsWith ("..") && !Path.IsPathRooted (SourceFileRelativeToRoot))
|
|
{
|
|
// SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
|
|
QMakeConfigFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
|
|
|
|
}
|
|
else
|
|
{
|
|
if (String.IsNullOrEmpty (GameProjectName))
|
|
{
|
|
// SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
|
|
QMakeConfigFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring (3) + "\" \\\n");
|
|
}
|
|
else if (!String.IsNullOrEmpty (GameProjectName))
|
|
{
|
|
QMakeConfigFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo (CurSourceFile, GameProjectPath) + "\" \\\n");
|
|
}
|
|
else
|
|
{
|
|
System.Console.WriteLine ("Error!, you should not be here.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Add section end to section strings;
|
|
QMakeSourceFilesList += QMakeSectionEnd;
|
|
QMakeHeaderFilesList += QMakeSectionEnd;
|
|
QMakeConfigFilesList += QMakeSectionEnd;
|
|
|
|
// Append sections to the QMakeLists.txt file
|
|
QMakeSourcePriFileContent.Append (QMakeSourceFilesList);
|
|
QMakeHeaderPriFileContent.Append (QMakeHeaderFilesList);
|
|
QMakeConfigPriFileContent.Append (QMakeConfigFilesList);
|
|
|
|
string QMakeProjectCmdArg = "";
|
|
|
|
foreach (string TargetFilePath in DiscoverTargets())
|
|
{
|
|
var TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFilePath); // Remove both ".cs" and ".
|
|
|
|
foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
|
|
{
|
|
if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development)
|
|
{
|
|
if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
|
|
{
|
|
|
|
if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
|
|
{
|
|
QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\"";
|
|
}
|
|
var ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration);
|
|
QMakeFileContent.Append(String.Format("{0}-Linux-{1}.commands = $$build {2} {0} Linux {1} $$args\n", TargetName, ConfName, QMakeProjectCmdArg));
|
|
QMakeTargetList += "\t" + TargetName + "-Linux-" + ConfName + " \\\n"; // , TargetName, ConfName);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
|
|
{
|
|
QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\"";
|
|
}
|
|
|
|
QMakeFileContent.Append(String.Format("{0}.commands = $$build {1} {0} Linux Development $$args\n\n", TargetName, QMakeProjectCmdArg));
|
|
QMakeTargetList += "\t" + TargetName + " \\\n";
|
|
}
|
|
|
|
QMakeFileContent.Append (QMakeTargetList.TrimEnd('\\'));
|
|
|
|
var FullFileName = Path.Combine(MasterProjectRelativePath, FileName);
|
|
|
|
var FullQMakeDefinesFileName = Path.Combine (MasterProjectRelativePath, QMakeDefinesFileName);
|
|
var FullQMakeIncludesFileName = Path.Combine(MasterProjectRelativePath, QMakeIncludesFileName);
|
|
var FullQMakeSourcePriFileName = Path.Combine(MasterProjectRelativePath, QMakeSourcePriFileName);
|
|
var FullQMakeHeaderPriFileName = Path.Combine(MasterProjectRelativePath, QMakeHeaderPriFileName);
|
|
var FullQMakeConfigPriFileName = Path.Combine(MasterProjectRelativePath, QMakeConfigPriFileName);
|
|
|
|
WriteFileIfChanged (FullQMakeDefinesFileName, QMakeDefinesPriFileContent.ToString ());
|
|
WriteFileIfChanged (FullQMakeIncludesFileName, QMakeIncludesPriFileContent.ToString());
|
|
WriteFileIfChanged (FullQMakeSourcePriFileName, QMakeSourcePriFileContent.ToString());
|
|
|
|
WriteFileIfChanged (FullQMakeHeaderPriFileName, QMakeHeaderPriFileContent.ToString());
|
|
WriteFileIfChanged (FullQMakeConfigPriFileName, QMakeConfigPriFileContent.ToString());
|
|
|
|
return WriteFileIfChanged (FullFileName, QMakeFileContent.ToString ());
|
|
}
|
|
|
|
/// ProjectFileGenerator interface
|
|
//protected override bool WriteMasterProjectFile( ProjectFile UBTProject )
|
|
protected override bool WriteProjectFiles ()
|
|
{
|
|
return WriteQMakePro();
|
|
}
|
|
|
|
/// ProjectFileGenerator interface
|
|
public override MasterProjectFolder AllocateMasterProjectFolder( ProjectFileGenerator InitOwnerProjectFileGenerator, string InitFolderName )
|
|
{
|
|
return new QMakefileFolder( InitOwnerProjectFileGenerator, InitFolderName );
|
|
}
|
|
|
|
/// ProjectFileGenerator interface
|
|
/// <summary>
|
|
/// Allocates a generator-specific project file object
|
|
/// </summary>
|
|
/// <param name="InitFilePath">Path to the project file</param>
|
|
/// <returns>The newly allocated project file object</returns>
|
|
protected override ProjectFile AllocateProjectFile( string InitFilePath )
|
|
{
|
|
return new QMakefileProjectFile( InitFilePath );
|
|
}
|
|
|
|
/// ProjectFileGenerator interface
|
|
public override void CleanProjectFiles(string InMasterProjectRelativePath, string InMasterProjectName, string InIntermediateProjectFilesPath)
|
|
{
|
|
}
|
|
}
|
|
}
|