146 lines
No EOL
5.6 KiB
C#
146 lines
No EOL
5.6 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Sharpmake;
|
|
using Configuration = Sharpmake.Project.Configuration;
|
|
|
|
namespace JustDance.Tools.Helpers
|
|
{
|
|
/// <summary>
|
|
/// Creates ntfs hard link to references instead of copying them locally,
|
|
/// in order to improve the build time and reduces the output size.
|
|
/// </summary>
|
|
/// <remarks>Should be called after all the projects have been resolved.</remarks>
|
|
internal static class CopyLocalOptimizer
|
|
{
|
|
public static void ConvertCopiesIntoHardlinks(this Project project)
|
|
{
|
|
foreach (var configuration in project.Configurations)
|
|
{
|
|
configuration.ConvertCopiesIntoHardlinks();
|
|
}
|
|
}
|
|
|
|
private static void ConvertCopiesIntoHardlinks(this Configuration configuration)
|
|
{
|
|
var dependencies = new HashSet<Configuration>();
|
|
var mklinker = Path.Combine(Globals.BranchRoot, @"extern\mklinker\mklinker.exe");
|
|
CollectDependenciesRecursive(dependencies, configuration);
|
|
|
|
var filesToCopy = dependencies.SelectMany(GetFilesToCopy).Concat(GetReferencesByPath(configuration));
|
|
|
|
foreach (var toCopy in filesToCopy)
|
|
{
|
|
var sourceFile = toCopy.Source;
|
|
var targetFile = Path.Combine(configuration.TargetPath, toCopy.RelativePath);
|
|
|
|
// C# supports a single declaration of post build events, we must replace the target
|
|
// configuration with its corresponding macro.
|
|
var postBuild = string.Format("\"{0}\" \"{1}\" \"{2}\"", mklinker, targetFile, sourceFile);
|
|
postBuild = postBuild.Replace(string.Format("\\{0}\\", configuration.Target.Name), "\\$(ConfigurationName)\\");
|
|
|
|
configuration.EventPostBuild.Add(postBuild);
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<FileToCopy> GetFilesToCopy(Configuration dependency)
|
|
{
|
|
var toCopy = new List<FileToCopy>();
|
|
|
|
toCopy.AddRange(GetCustomBuildActionFiles(dependency));
|
|
toCopy.AddRange(GetReferencesByPath(dependency));
|
|
|
|
toCopy.Add(FileToCopy.Create(Path.Combine(dependency.TargetPath, dependency.TargetFileFullName + GetAssemblyExtension(dependency))));
|
|
toCopy.Add(FileToCopy.Create(Path.Combine(dependency.TargetPath, dependency.TargetFileFullName + ".pdb")));
|
|
|
|
return toCopy;
|
|
}
|
|
|
|
private static IEnumerable<FileToCopy> GetReferencesByPath(Configuration dependency)
|
|
{
|
|
return dependency.ReferencesByPath.Select(file => Util.PathGetAbsolute(dependency.TargetPath, file)).Select(FileToCopy.Create);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the files in the project that are copied to output. They should be relative to their folder.
|
|
/// </summary>
|
|
private static IEnumerable<FileToCopy> GetCustomBuildActionFiles(Configuration dependency)
|
|
{
|
|
var project = dependency.Project as CSharpProject;
|
|
|
|
if (project != null)
|
|
{
|
|
return from additionalFile in project.AdditionalContentAlwaysCopy.Concat(project.AdditionalContentCopyIfNewer)
|
|
let absolutePath = Path.Combine(project.SourceRootPath, additionalFile)
|
|
from file in ExpandWildcards(absolutePath)
|
|
select new FileToCopy
|
|
{
|
|
Source = file,
|
|
RelativePath = Util.PathGetRelative(project.SourceRootPath, file)
|
|
};
|
|
}
|
|
return new FileToCopy[0];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Expands the * into their files.
|
|
/// </summary>
|
|
private static IEnumerable<string> ExpandWildcards(string sourceFile)
|
|
{
|
|
if (sourceFile.EndsWith("*"))
|
|
{
|
|
var directory = sourceFile.TrimEnd('*');
|
|
if (Directory.Exists(directory))
|
|
{
|
|
foreach (var file in Directory.GetFiles(directory, "*", SearchOption.AllDirectories))
|
|
{
|
|
yield return file;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
yield return sourceFile;
|
|
}
|
|
}
|
|
|
|
private static void CollectDependenciesRecursive(HashSet<Configuration> configurations, Configuration configuration)
|
|
{
|
|
foreach (var dependency in configuration.ResolvedDependencies)
|
|
{
|
|
if (configurations.Add(dependency))
|
|
{
|
|
CollectDependenciesRecursive(configurations, dependency);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static string GetAssemblyExtension(Configuration dependency)
|
|
{
|
|
return (dependency.Output == Configuration.OutputType.Exe ||
|
|
dependency.Output == Configuration.OutputType.DotNetWindowsApp ||
|
|
dependency.Output == Configuration.OutputType.DotNetConsoleApp) ? ".exe" : ".dll";
|
|
}
|
|
|
|
private struct FileToCopy
|
|
{
|
|
/// <summary>
|
|
/// The full path of the sourceFolder file.
|
|
/// </summary>
|
|
public string Source { get; set; }
|
|
/// <summary>
|
|
/// The destination relative to the output.
|
|
/// </summary>
|
|
public string RelativePath { get; set; }
|
|
|
|
public static FileToCopy Create(string source)
|
|
{
|
|
return new FileToCopy
|
|
{
|
|
Source = source,
|
|
RelativePath = Path.GetFileName(source)
|
|
};
|
|
}
|
|
}
|
|
}
|
|
} |