You're breathtaking!
This commit is contained in:
19
Source/Tools/Flax.Build/Deploy/Configuration.cs
Normal file
19
Source/Tools/Flax.Build/Deploy/Configuration.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace Flax.Build
|
||||
{
|
||||
public static partial class Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds and packages the editor.
|
||||
/// </summary>
|
||||
[CommandLine("deployEditor", "Builds and packages the editor.")]
|
||||
public static bool DeployEditor;
|
||||
|
||||
/// <summary>
|
||||
/// Builds and packages the platforms data.
|
||||
/// </summary>
|
||||
[CommandLine("deployPlatforms", "Builds and packages the platforms data.")]
|
||||
public static bool DeployPlatforms;
|
||||
}
|
||||
}
|
||||
126
Source/Tools/Flax.Build/Deploy/Deployer.cs
Normal file
126
Source/Tools/Flax.Build/Deploy/Deployer.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) 2012-2020 Flax Engine. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Flax.Build;
|
||||
|
||||
namespace Flax.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// The automation and deployment utility.
|
||||
/// </summary>
|
||||
class Deployer
|
||||
{
|
||||
public static string PackageOutputPath;
|
||||
public static int VersionMajor;
|
||||
public static int VersionMinor;
|
||||
public static int VersionBuild;
|
||||
|
||||
public static bool Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (Configuration.DeployEditor)
|
||||
{
|
||||
BuildEditor();
|
||||
Deployment.Editor.Package();
|
||||
}
|
||||
|
||||
if (Configuration.DeployPlatforms)
|
||||
{
|
||||
BuildPlatform(TargetPlatform.Linux, TargetArchitecture.x64);
|
||||
BuildPlatform(TargetPlatform.UWP, TargetArchitecture.x64);
|
||||
BuildPlatform(TargetPlatform.Windows, TargetArchitecture.x64);
|
||||
BuildPlatform(TargetPlatform.Android, TargetArchitecture.ARM64);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Build failed!");
|
||||
Log.Exception(ex);
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Initialize()
|
||||
{
|
||||
// Read the current engine version
|
||||
var engineVersion = EngineTarget.EngineVersion;
|
||||
VersionMajor = engineVersion.Major;
|
||||
VersionMinor = engineVersion.Minor;
|
||||
VersionBuild = engineVersion.Build;
|
||||
|
||||
// Generate the engine build config
|
||||
var buildConfigHeader = new StringBuilder();
|
||||
{
|
||||
buildConfigHeader.AppendLine("#pragma once");
|
||||
buildConfigHeader.AppendLine();
|
||||
buildConfigHeader.AppendLine("#define COMPILE_WITH_DEV_ENV 0");
|
||||
buildConfigHeader.AppendLine("#define OFFICIAL_BUILD 1");
|
||||
}
|
||||
Utilities.WriteFileIfChanged(Path.Combine(Globals.EngineRoot, "Source/Engine/Core/Config.Gen.h"), buildConfigHeader.ToString());
|
||||
|
||||
// Prepare the package output
|
||||
PackageOutputPath = Path.Combine(Globals.EngineRoot, string.Format("Package_{0}_{1:00}_{2:00000}", VersionMajor, VersionMinor, VersionBuild));
|
||||
Utilities.DirectoryDelete(PackageOutputPath);
|
||||
Directory.CreateDirectory(PackageOutputPath);
|
||||
|
||||
Log.Info(string.Empty);
|
||||
Log.Info(string.Empty);
|
||||
}
|
||||
|
||||
private static void Cleanup()
|
||||
{
|
||||
#if false
|
||||
// Restore the generated config file (could resource with git but do it here just in case)
|
||||
using (var writer = new StreamWriter(Path.Combine(ProjectRoot, "Source/Engine/Core/Config.Gen.h")))
|
||||
{
|
||||
writer.WriteLine("#pragma once");
|
||||
writer.WriteLine();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void BuildEditor()
|
||||
{
|
||||
FlaxBuild.Build(Globals.EngineRoot, "FlaxEditor", TargetPlatform.Windows, TargetArchitecture.x64, TargetConfiguration.Debug);
|
||||
FlaxBuild.Build(Globals.EngineRoot, "FlaxEditor", TargetPlatform.Windows, TargetArchitecture.x64, TargetConfiguration.Development);
|
||||
FlaxBuild.Build(Globals.EngineRoot, "FlaxEditor", TargetPlatform.Windows, TargetArchitecture.x64, TargetConfiguration.Release);
|
||||
}
|
||||
|
||||
private static bool CannotBuildPlatform(TargetPlatform platform)
|
||||
{
|
||||
if (!Platform.BuildPlatform.CanBuildPlatform(platform))
|
||||
{
|
||||
Log.Warning(string.Format("Cannot build for {0} on {1}", platform, Platform.BuildPlatform.Target));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void BuildPlatform(TargetPlatform platform, params TargetArchitecture[] architectures)
|
||||
{
|
||||
if (CannotBuildPlatform(platform))
|
||||
return;
|
||||
|
||||
foreach (var architecture in architectures)
|
||||
{
|
||||
FlaxBuild.Build(Globals.EngineRoot, "FlaxGame", platform, architecture, TargetConfiguration.Debug);
|
||||
FlaxBuild.Build(Globals.EngineRoot, "FlaxGame", platform, architecture, TargetConfiguration.Development);
|
||||
FlaxBuild.Build(Globals.EngineRoot, "FlaxGame", platform, architecture, TargetConfiguration.Release);
|
||||
}
|
||||
|
||||
Deployment.Platforms.Package(platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
181
Source/Tools/Flax.Build/Deploy/Deployment.Editor.cs
Normal file
181
Source/Tools/Flax.Build/Deploy/Deployment.Editor.cs
Normal file
@@ -0,0 +1,181 @@
|
||||
// Copyright (c) 2012-2020 Flax Engine. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Flax.Build;
|
||||
using Ionic.Zip;
|
||||
using Ionic.Zlib;
|
||||
|
||||
namespace Flax.Deploy
|
||||
{
|
||||
partial class Deployment
|
||||
{
|
||||
public class Editor
|
||||
{
|
||||
private static string RootPath;
|
||||
private static string OutputPath;
|
||||
|
||||
public static void Package()
|
||||
{
|
||||
// Prepare
|
||||
RootPath = Globals.EngineRoot;
|
||||
OutputPath = Path.Combine(Deployer.PackageOutputPath, "Editor");
|
||||
Directory.CreateDirectory(OutputPath);
|
||||
Log.Info(string.Empty);
|
||||
Log.Info("Deploy editor files");
|
||||
Log.Info(string.Empty);
|
||||
|
||||
// Deploy binaries
|
||||
DeployEditorBinaries(TargetConfiguration.Debug);
|
||||
DeployEditorBinaries(TargetConfiguration.Development);
|
||||
DeployEditorBinaries(TargetConfiguration.Release);
|
||||
{
|
||||
var binariesSubDir = "Binaries/Tools";
|
||||
var src = Path.Combine(RootPath, binariesSubDir);
|
||||
var dst = Path.Combine(OutputPath, binariesSubDir);
|
||||
|
||||
DeployFile(src, dst, "Flax.Build.exe");
|
||||
DeployFile(src, dst, "Flax.Build.xml");
|
||||
DeployFile(src, dst, "Ionic.Zip.Reduced.dll");
|
||||
DeployFile(src, dst, "Newtonsoft.Json.dll");
|
||||
}
|
||||
|
||||
// Deploy content
|
||||
DeployFolder(RootPath, OutputPath, "Content");
|
||||
|
||||
// Deploy Mono runtime data files
|
||||
if (Platform.BuildPlatform.Target == TargetPlatform.Windows)
|
||||
{
|
||||
DeployFolder(RootPath, OutputPath, "Source/Platforms/Editor/Windows/Mono");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
// Deploy DotNet deps
|
||||
{
|
||||
var subDir = "Source/Platforms/DotNet";
|
||||
DeployFile(RootPath, OutputPath, subDir, "Newtonsoft.Json.dll");
|
||||
DeployFile(RootPath, OutputPath, subDir, "Newtonsoft.Json.xml");
|
||||
}
|
||||
|
||||
// Deploy sources
|
||||
{
|
||||
// Modules public files
|
||||
var rules = Builder.GenerateRulesAssembly();
|
||||
var files = new List<string>();
|
||||
foreach (var module in rules.Modules)
|
||||
{
|
||||
module.GetFilesToDeploy(files);
|
||||
files.Add(module.FilePath);
|
||||
foreach (var file in files)
|
||||
{
|
||||
var src = Path.GetDirectoryName(file);
|
||||
var dst = Path.Combine(OutputPath, Utilities.MakePathRelativeTo(src, RootPath));
|
||||
var filename = Path.GetFileName(file);
|
||||
DeployFile(src, dst, filename);
|
||||
}
|
||||
files.Clear();
|
||||
}
|
||||
|
||||
// Shader includes
|
||||
var shaders = Directory.GetFiles(Path.Combine(RootPath, "Source/Shaders"), "*.hlsl", SearchOption.AllDirectories);
|
||||
foreach (var shader in shaders)
|
||||
{
|
||||
var localPath = Utilities.MakePathRelativeTo(shader, RootPath);
|
||||
DeployFile(shader, Path.Combine(OutputPath, localPath));
|
||||
}
|
||||
|
||||
// Custom engine files
|
||||
DeployFile(RootPath, OutputPath, "Source/ThirdParty", "concurrentqueue.h");
|
||||
DeployFile(RootPath, OutputPath, "Source", ".editorconfig");
|
||||
DeployFile(RootPath, OutputPath, "Source", "flax.natvis");
|
||||
DeployFile(RootPath, OutputPath, "Source", "FlaxEditor.Build.cs");
|
||||
DeployFile(RootPath, OutputPath, "Source", "FlaxEngine.Gen.h");
|
||||
DeployFile(RootPath, OutputPath, "Source", "FlaxGame.Build.cs");
|
||||
|
||||
// Mark deployed sources as already prebuilt
|
||||
Utilities.ReplaceInFile(Path.Combine(OutputPath, "Source/FlaxEditor.Build.cs"), "IsPreBuilt = false;", "IsPreBuilt = true;");
|
||||
Utilities.ReplaceInFile(Path.Combine(OutputPath, "Source/FlaxGame.Build.cs"), "IsPreBuilt = false;", "IsPreBuilt = true;");
|
||||
}
|
||||
|
||||
// Deploy project
|
||||
DeployFile(RootPath, OutputPath, "Flax.flaxproj");
|
||||
|
||||
// Compress
|
||||
Log.Info(string.Empty);
|
||||
Log.Info("Compressing editor files...");
|
||||
var editorPackageZipPath = Path.Combine(Deployer.PackageOutputPath, "Editor.zip");
|
||||
using (ZipFile zip = new ZipFile())
|
||||
{
|
||||
zip.AddDirectory(OutputPath);
|
||||
|
||||
zip.CompressionLevel = CompressionLevel.BestCompression;
|
||||
zip.Comment = string.Format("Flax Editor {0}.{1}.{2}\nDate: {3}", Deployer.VersionMajor, Deployer.VersionMinor, Deployer.VersionBuild, DateTime.UtcNow);
|
||||
|
||||
zip.Save(editorPackageZipPath);
|
||||
}
|
||||
Log.Info("Compressed editor package size: " + Utilities.GetFileSize(editorPackageZipPath));
|
||||
|
||||
Log.Info("Compressing editor debug symbols files...");
|
||||
editorPackageZipPath = Path.Combine(Deployer.PackageOutputPath, "EditorDebugSymbols.zip");
|
||||
using (ZipFile zip = new ZipFile())
|
||||
{
|
||||
zip.AddDirectory(Path.Combine(Deployer.PackageOutputPath, "EditorDebugSymbols"));
|
||||
|
||||
zip.CompressionLevel = CompressionLevel.BestCompression;
|
||||
zip.Comment = string.Format("Flax Editor {0}.{1}.{2}\nDate: {3}", Deployer.VersionMajor, Deployer.VersionMinor, Deployer.VersionBuild, DateTime.UtcNow);
|
||||
|
||||
zip.Save(editorPackageZipPath);
|
||||
}
|
||||
Log.Info("Compressed editor debug symbols package size: " + Utilities.GetFileSize(editorPackageZipPath));
|
||||
|
||||
// Cleanup
|
||||
Utilities.DirectoryDelete(OutputPath);
|
||||
Utilities.DirectoryDelete(Path.Combine(Deployer.PackageOutputPath, "EditorDebugSymbols"));
|
||||
}
|
||||
|
||||
private static void DeployEditorBinaries(TargetConfiguration configuration)
|
||||
{
|
||||
if (Platform.BuildPlatform.Target == TargetPlatform.Windows)
|
||||
{
|
||||
var binariesSubDir = "Binaries/Editor/Win64/" + configuration;
|
||||
var src = Path.Combine(RootPath, binariesSubDir);
|
||||
var dst = Path.Combine(OutputPath, binariesSubDir);
|
||||
var dstDebug = Path.Combine(Deployer.PackageOutputPath, "EditorDebugSymbols/Win64/" + configuration);
|
||||
Directory.CreateDirectory(dst);
|
||||
Directory.CreateDirectory(dstDebug);
|
||||
|
||||
// Validate that build editor app has a valid version number
|
||||
var editorExeName = "FlaxEditor.exe";
|
||||
var version = FileVersionInfo.GetVersionInfo(Path.Combine(src, editorExeName));
|
||||
if (version.FileMajorPart != Deployer.VersionMajor || version.FileMinorPart != Deployer.VersionMinor || version.FileBuildPart != Deployer.VersionBuild)
|
||||
{
|
||||
throw new InvalidDataException("Invalid engine build number. Output " + editorExeName + " has not matching version number.");
|
||||
}
|
||||
|
||||
// Deploy binaries
|
||||
DeployFile(src, dst, editorExeName);
|
||||
DeployFile(src, dst, "FlaxEditor.Build.json");
|
||||
DeployFile(src, dst, "FlaxEditor.lib");
|
||||
DeployFile(src, dst, "FlaxEngine.CSharp.pdb");
|
||||
DeployFile(src, dst, "FlaxEngine.CSharp.xml");
|
||||
DeployFile(src, dst, "Newtonsoft.Json.pdb");
|
||||
DeployFiles(src, dst, "*.dll");
|
||||
|
||||
// Deploy debug symbols files
|
||||
DeployFiles(src, dstDebug, "*.pdb");
|
||||
File.Delete(Path.Combine(dstDebug, "FlaxEngine.CSharp.pdb"));
|
||||
File.Delete(Path.Combine(dstDebug, "Newtonsoft.Json.pdb"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Source/Tools/Flax.Build/Deploy/Deployment.Platforms.cs
Normal file
76
Source/Tools/Flax.Build/Deploy/Deployment.Platforms.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2012-2020 Flax Engine. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Flax.Build;
|
||||
using Ionic.Zip;
|
||||
using Ionic.Zlib;
|
||||
|
||||
namespace Flax.Deploy
|
||||
{
|
||||
partial class Deployment
|
||||
{
|
||||
public class Platforms
|
||||
{
|
||||
public static void Package(TargetPlatform platform)
|
||||
{
|
||||
var platformsRoot = Path.Combine(Globals.EngineRoot, "Source", "Platforms");
|
||||
|
||||
Log.Info(string.Empty);
|
||||
Log.Info($"Deploy {platform} platform files");
|
||||
Log.Info(string.Empty);
|
||||
|
||||
string platformName = platform.ToString();
|
||||
string src = Path.Combine(platformsRoot, platformName);
|
||||
string dst = Path.Combine(Deployer.PackageOutputPath, platformName);
|
||||
|
||||
// Deploy files
|
||||
{
|
||||
DeployFolder(platformsRoot, Deployer.PackageOutputPath, platformName);
|
||||
|
||||
// For Linux don't deploy engine libs used by C++ scripting linking (engine source required)
|
||||
if (platform == TargetPlatform.Linux)
|
||||
{
|
||||
File.Delete(Path.Combine(dst, "Binaries", "Game", "x64", "Debug", "FlaxGame.a"));
|
||||
File.Delete(Path.Combine(dst, "Binaries", "Game", "x64", "Development", "FlaxGame.a"));
|
||||
File.Delete(Path.Combine(dst, "Binaries", "Game", "x64", "Release", "FlaxGame.a"));
|
||||
}
|
||||
|
||||
// Don't distribute engine deps
|
||||
Utilities.DirectoryDelete(Path.Combine(dst, "Binaries", "ThirdParty"));
|
||||
|
||||
var filesToRemove = new List<string>();
|
||||
filesToRemove.AddRange(Directory.GetFiles(dst, ".gitignore", SearchOption.AllDirectories));
|
||||
filesToRemove.AddRange(Directory.GetFiles(dst, "*.pdb", SearchOption.AllDirectories));
|
||||
filesToRemove.AddRange(Directory.GetFiles(dst, "*.ilk", SearchOption.AllDirectories));
|
||||
filesToRemove.AddRange(Directory.GetFiles(dst, "*.exp", SearchOption.AllDirectories));
|
||||
filesToRemove.ForEach(File.Delete);
|
||||
}
|
||||
|
||||
// Compress
|
||||
{
|
||||
Log.Info("Compressing platform files...");
|
||||
|
||||
var packageZipPath = Path.Combine(Deployer.PackageOutputPath, platformName + ".zip");
|
||||
using (ZipFile zip = new ZipFile())
|
||||
{
|
||||
zip.AddDirectory(dst);
|
||||
|
||||
zip.CompressionLevel = CompressionLevel.BestCompression;
|
||||
zip.Comment = string.Format("Flax Engine {0}.{1}.{2}\nPlatform: {4}\nDate: {3}", Deployer.VersionMajor, Deployer.VersionMinor, Deployer.VersionBuild, DateTime.UtcNow, platformName);
|
||||
|
||||
zip.Save(packageZipPath);
|
||||
}
|
||||
|
||||
Log.Info(string.Format("Compressed {0} package size: {1}", platformName, Utilities.GetFileSize(packageZipPath)));
|
||||
}
|
||||
|
||||
// Remove files (only zip package is used)
|
||||
Utilities.DirectoryDelete(dst);
|
||||
|
||||
Log.Info(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Source/Tools/Flax.Build/Deploy/Deployment.Utils.cs
Normal file
85
Source/Tools/Flax.Build/Deploy/Deployment.Utils.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2012-2020 Flax Engine. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Flax.Build;
|
||||
|
||||
namespace Flax.Deploy
|
||||
{
|
||||
partial class Deployment
|
||||
{
|
||||
private static void DeployFiles(string src, string dst, string searchPattern)
|
||||
{
|
||||
if (!Directory.Exists(dst))
|
||||
Directory.CreateDirectory(dst);
|
||||
|
||||
string[] files = Directory.GetFiles(src, searchPattern);
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
var filename = Path.GetFileName(files[i]);
|
||||
|
||||
Log.Verbose("Deploy file " + filename);
|
||||
|
||||
File.Copy(files[i], Path.Combine(dst, filename));
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeployFile(string srcPath, string dstPath, bool optional = false)
|
||||
{
|
||||
Log.Verbose("Deploy file " + Path.GetFileName(srcPath));
|
||||
|
||||
var dst = Path.GetDirectoryName(dstPath);
|
||||
if (!Directory.Exists(dst))
|
||||
Directory.CreateDirectory(dst);
|
||||
|
||||
if (!File.Exists(srcPath))
|
||||
{
|
||||
if (optional)
|
||||
return;
|
||||
throw new Exception("Missing source file " + srcPath);
|
||||
}
|
||||
|
||||
File.Copy(srcPath, dstPath);
|
||||
}
|
||||
|
||||
private static void DeployFile(string src, string dst, string filename, bool optional = false)
|
||||
{
|
||||
Log.Verbose("Deploy file " + filename);
|
||||
|
||||
if (!Directory.Exists(dst))
|
||||
Directory.CreateDirectory(dst);
|
||||
|
||||
var srcPath = Path.Combine(src, filename);
|
||||
if (!File.Exists(srcPath))
|
||||
{
|
||||
if (optional)
|
||||
return;
|
||||
throw new Exception("Missing source file " + srcPath);
|
||||
}
|
||||
|
||||
File.Copy(srcPath, Path.Combine(dst, filename));
|
||||
}
|
||||
|
||||
private static void DeployFile(string src, string dst, string subdir, string filename)
|
||||
{
|
||||
Log.Verbose("Deploy file " + subdir + "/" + filename);
|
||||
|
||||
string dstPath = Path.Combine(dst, subdir);
|
||||
if (!Directory.Exists(dstPath))
|
||||
Directory.CreateDirectory(dstPath);
|
||||
|
||||
var srcPath = Path.Combine(src, subdir, filename);
|
||||
if (!File.Exists(srcPath))
|
||||
throw new Exception("Missing source file " + srcPath);
|
||||
|
||||
File.Copy(srcPath, Path.Combine(dstPath, filename));
|
||||
}
|
||||
|
||||
private static void DeployFolder(string src, string dst, string subdir)
|
||||
{
|
||||
Log.Verbose("Deploy folder " + subdir);
|
||||
|
||||
Utilities.DirectoryCopy(Path.Combine(src, subdir), Path.Combine(dst, subdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Source/Tools/Flax.Build/Deploy/FlaxBuild.cs
Normal file
41
Source/Tools/Flax.Build/Deploy/FlaxBuild.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2012-2020 Flax Engine. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Flax.Build;
|
||||
|
||||
namespace Flax.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Flax.Build environment and tools.
|
||||
/// </summary>
|
||||
class FlaxBuild
|
||||
{
|
||||
public static void Build(string root, string target, TargetPlatform platform, TargetArchitecture architecture, TargetConfiguration configuration)
|
||||
{
|
||||
var buildPlatform = Platform.BuildPlatform.Target;
|
||||
var flaxBuildTool = Path.Combine(Globals.EngineRoot, "Binaries/Tools/Flax.Build.exe");
|
||||
var format = "-build -buildtargets={0} -log -logfile= -perf -platform={1} -arch={2} -configuration={3}";
|
||||
if (buildPlatform == TargetPlatform.Linux)
|
||||
{
|
||||
format = format.Replace("-", "--");
|
||||
}
|
||||
var cmdLine = string.Format(format, target, platform, architecture, configuration);
|
||||
|
||||
int result;
|
||||
if (buildPlatform == TargetPlatform.Windows)
|
||||
{
|
||||
result = Utilities.Run(flaxBuildTool, cmdLine, null, root);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Utilities.Run("mono", flaxBuildTool + " " + cmdLine, null, root);
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
throw new Exception(string.Format("Unable to build target {0}. Flax.Build failed. See log to learn more.", target));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
263
Source/Tools/Flax.Build/Deploy/VCEnvironment.cs
Normal file
263
Source/Tools/Flax.Build/Deploy/VCEnvironment.cs
Normal file
@@ -0,0 +1,263 @@
|
||||
// Copyright (c) 2012-2020 Flax Engine. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Flax.Build;
|
||||
using Flax.Build.Platforms;
|
||||
using Flax.Build.Projects.VisualStudio;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Flax.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores information about a Visual C++ installation and compile environment.
|
||||
/// </summary>
|
||||
public static class VCEnvironment
|
||||
{
|
||||
private static string _msBuildPath;
|
||||
private static string _cscPath;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the MSBuild executable.
|
||||
/// </summary>
|
||||
public static string MSBuildPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_msBuildPath == null)
|
||||
_msBuildPath = GetMSBuildToolPath();
|
||||
return _msBuildPath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the C# compiler executable.
|
||||
/// </summary>
|
||||
public static string CscPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_cscPath == null)
|
||||
_cscPath = GetCscPath();
|
||||
return _cscPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetMSBuildToolPath()
|
||||
{
|
||||
string toolPath;
|
||||
switch (Platform.BuildPlatform.Target)
|
||||
{
|
||||
case TargetPlatform.Linux:
|
||||
{
|
||||
// Use msbuild from Mono
|
||||
toolPath = UnixPlatform.Which("msbuild");
|
||||
if (toolPath != null)
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TargetPlatform.Windows:
|
||||
{
|
||||
var visualStudioInstances = VisualStudioInstance.GetInstances();
|
||||
foreach (var visualStudioInstance in visualStudioInstances)
|
||||
{
|
||||
toolPath = Path.Combine(visualStudioInstance.Path, "MSBuild\\Current\\Bin\\MSBuild.exe");
|
||||
if (File.Exists(toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\VisualStudio\\SxS\\VS7", "15.0", "MSBuild\\15.0\\bin\\MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
toolPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "MSBuild", "14.0", "bin", "MSBuild.exe");
|
||||
if (File.Exists(toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\14.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\12.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\4.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string GetCscPath()
|
||||
{
|
||||
string toolPath;
|
||||
switch (Platform.BuildPlatform.Target)
|
||||
{
|
||||
case TargetPlatform.Linux:
|
||||
{
|
||||
// Use csc from Mono
|
||||
toolPath = UnixPlatform.Which("csc");
|
||||
if (toolPath != null)
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TargetPlatform.Windows:
|
||||
{
|
||||
if (TryReadInstallPath("Microsoft\\VisualStudio\\SxS\\VS7", "15.0", "MSBuild\\15.0\\bin\\csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
toolPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "MSBuild", "14.0", "bin", "csc.exe");
|
||||
if (File.Exists(toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\14.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\12.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\4.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to query the registry under HKCU/HKLM Win32/Wow64 software registry keys for a certain install directory.
|
||||
/// </summary>
|
||||
/// <returns>True if found MsBuild tool, otherwise false.</returns>
|
||||
private static bool TryReadInstallPath(string keyRelativePath, string keyName, string msBuildRelativePath, out string outMsBuildPath)
|
||||
{
|
||||
string[] keyBasePaths =
|
||||
{
|
||||
@"HKEY_CURRENT_USER\SOFTWARE\",
|
||||
@"HKEY_LOCAL_MACHINE\SOFTWARE\",
|
||||
@"HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\",
|
||||
@"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\"
|
||||
};
|
||||
|
||||
foreach (string keyBasePath in keyBasePaths)
|
||||
{
|
||||
if (Registry.GetValue(keyBasePath + keyRelativePath, keyName, null) is string value)
|
||||
{
|
||||
string msBuildPath = Path.Combine(value, msBuildRelativePath);
|
||||
if (File.Exists(msBuildPath))
|
||||
{
|
||||
outMsBuildPath = msBuildPath;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outMsBuildPath = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs msbuild.exe with the specified arguments.
|
||||
/// </summary>
|
||||
/// <param name="project">Path to the project to build.</param>
|
||||
/// <param name="buildConfig">Configuration to build.</param>
|
||||
/// <param name="buildPlatform">Platform to build.</param>
|
||||
public static void BuildProject(string project, string buildConfig, string buildPlatform)
|
||||
{
|
||||
var msBuild = MSBuildPath;
|
||||
if (string.IsNullOrEmpty(msBuild))
|
||||
{
|
||||
throw new Exception(string.Format("Unable to find msbuild.exe at: \"{0}\"", msBuild));
|
||||
}
|
||||
|
||||
if (!File.Exists(project))
|
||||
{
|
||||
throw new Exception(string.Format("Project {0} does not exist!", project));
|
||||
}
|
||||
|
||||
string cmdLine = string.Format("\"{0}\" /m /t:Build /p:Configuration=\"{1}\" /p:Platform=\"{2}\" /verbosity:minimal /nologo", project, buildConfig, buildPlatform);
|
||||
int result = Utilities.Run(msBuild, cmdLine);
|
||||
if (result != 0)
|
||||
{
|
||||
throw new Exception(string.Format("Unable to build project {0}. MSBuild failed. See log to learn more.", project));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a Visual Studio solution with MsBuild.
|
||||
/// </summary>
|
||||
/// <param name="solutionFile">Path to the solution file</param>
|
||||
/// <param name="buildConfig">Configuration to build.</param>
|
||||
/// <param name="buildPlatform">Platform to build.</param>
|
||||
public static void BuildSolution(string solutionFile, string buildConfig, string buildPlatform)
|
||||
{
|
||||
var msBuild = MSBuildPath;
|
||||
if (string.IsNullOrEmpty(msBuild))
|
||||
{
|
||||
throw new Exception(string.Format("Unable to find msbuild.exe at: \"{0}\"", msBuild));
|
||||
}
|
||||
|
||||
if (!File.Exists(solutionFile))
|
||||
{
|
||||
throw new Exception(string.Format("Unable to build solution {0}. Solution file not found.", solutionFile));
|
||||
}
|
||||
|
||||
string cmdLine = string.Format("\"{0}\" /m /t:Build /p:Configuration=\"{1}\" /p:Platform=\"{2}\" /verbosity:minimal /nologo", solutionFile, buildConfig, buildPlatform);
|
||||
int result = Utilities.Run(msBuild, cmdLine);
|
||||
if (result != 0)
|
||||
{
|
||||
throw new Exception(string.Format("Unable to build solution {0}. MSBuild failed. See log to learn more.", solutionFile));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the build a Visual Studio solution cache with MsBuild.
|
||||
/// </summary>
|
||||
/// <param name="solutionFile">Path to the solution file</param>
|
||||
public static void CleanSolution(string solutionFile)
|
||||
{
|
||||
var msBuild = MSBuildPath;
|
||||
if (string.IsNullOrEmpty(msBuild))
|
||||
{
|
||||
throw new Exception(string.Format("Unable to find msbuild.exe at: \"{0}\"", msBuild));
|
||||
}
|
||||
|
||||
if (!File.Exists(solutionFile))
|
||||
{
|
||||
throw new Exception(string.Format("Unable to clean solution {0}. Solution file not found.", solutionFile));
|
||||
}
|
||||
|
||||
string cmdLine = string.Format("\"{0}\" /t:Clean /verbosity:minimal /nologo", solutionFile);
|
||||
Utilities.Run(msBuild, cmdLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user