Fix restoring NuGet packages for target with multiple projects
Fix restoring `NuGet` packages to run before project build to ensure files are downloaded #3900
This commit is contained in:
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Flax.Build.Graph;
|
||||
using Flax.Build.NativeCpp;
|
||||
|
||||
@@ -424,5 +425,65 @@ namespace Flax.Build
|
||||
|
||||
return failed;
|
||||
}
|
||||
|
||||
private static void DeployFiles(TaskGraph graph, Target target, BuildOptions targetBuildOptions, string outputPath)
|
||||
{
|
||||
using (new ProfileEventScope("DeployFiles"))
|
||||
{
|
||||
foreach (var srcFile in targetBuildOptions.OptionalDependencyFiles.Where(File.Exists).Union(targetBuildOptions.DependencyFiles))
|
||||
{
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(srcFile));
|
||||
graph.AddCopyFile(dstFile, srcFile);
|
||||
}
|
||||
|
||||
if (targetBuildOptions.NugetPackageReferences.Any())
|
||||
{
|
||||
var nugetPath = Utilities.GetNugetPackagesPath();
|
||||
var restore = true;
|
||||
foreach (var reference in targetBuildOptions.NugetPackageReferences)
|
||||
{
|
||||
var path = reference.GetLibPath(nugetPath);
|
||||
if (!File.Exists(path) && restore)
|
||||
{
|
||||
RestoreNugetPackages(graph, target, targetBuildOptions);
|
||||
restore = false;
|
||||
}
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(path));
|
||||
graph.AddCopyFile(dstFile, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RestoreNugetPackages(TaskGraph graph, Target target, BuildOptions targetBuildOptions)
|
||||
{
|
||||
// Generate a dummy csproj file to restore package from it
|
||||
var csprojPath = Path.Combine(targetBuildOptions.IntermediateFolder, "nuget.restore.csproj");
|
||||
var dotnetSdk = DotNetSdk.Instance;
|
||||
var csProjectFileContent = new StringBuilder();
|
||||
csProjectFileContent.AppendLine("<Project Sdk=\"Microsoft.NET.Sdk\">");
|
||||
csProjectFileContent.AppendLine(" <PropertyGroup>");
|
||||
csProjectFileContent.AppendLine($" <TargetFramework>net{dotnetSdk.Version.Major}.{dotnetSdk.Version.Minor}</TargetFramework>");
|
||||
csProjectFileContent.AppendLine(" <IsPackable>false</IsPackable>");
|
||||
csProjectFileContent.AppendLine(" <EnableDefaultItems>false</EnableDefaultItems>");
|
||||
csProjectFileContent.AppendLine(" <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>");
|
||||
csProjectFileContent.AppendLine(" <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>");
|
||||
csProjectFileContent.AppendLine(" <EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning>");
|
||||
csProjectFileContent.AppendLine(" <GenerateAssemblyInfo>false</GenerateAssemblyInfo>");
|
||||
csProjectFileContent.AppendLine($" <LangVersion>{dotnetSdk.CSharpLanguageVersion}</LangVersion>");
|
||||
csProjectFileContent.AppendLine(" <FileAlignment>512</FileAlignment>");
|
||||
csProjectFileContent.AppendLine(" <RestorePackages>true</RestorePackages>");
|
||||
csProjectFileContent.AppendLine(" </PropertyGroup>");
|
||||
csProjectFileContent.AppendLine(" <ItemGroup>");
|
||||
foreach (var reference in targetBuildOptions.NugetPackageReferences)
|
||||
csProjectFileContent.AppendLine($" <PackageReference Include=\"{reference.Name}\" Version=\"{reference.Version}\" />");
|
||||
csProjectFileContent.AppendLine(" </ItemGroup>");
|
||||
csProjectFileContent.AppendLine("</Project>");
|
||||
Utilities.WriteFileIfChanged(csprojPath, csProjectFileContent.ToString());
|
||||
|
||||
// Restore packages using dotnet CLI (synchronous to prevent task ordering issues on C# library building)
|
||||
Log.Info($"Restoring NuGet packages for target {target.Name}");
|
||||
Utilities.Run(Utilities.GetDotNetPath(), $"restore \"{csprojPath}\"", null, null, Utilities.RunOptions.DefaultTool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,27 +135,7 @@ namespace Flax.Build
|
||||
// Deploy files
|
||||
if (!target.IsPreBuilt)
|
||||
{
|
||||
using (new ProfileEventScope("DeployFiles"))
|
||||
{
|
||||
foreach (var srcFile in targetBuildOptions.OptionalDependencyFiles.Where(File.Exists).Union(targetBuildOptions.DependencyFiles))
|
||||
{
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(srcFile));
|
||||
graph.AddCopyFile(dstFile, srcFile);
|
||||
}
|
||||
|
||||
if (targetBuildOptions.NugetPackageReferences.Any())
|
||||
{
|
||||
var nugetPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
||||
foreach (var reference in targetBuildOptions.NugetPackageReferences)
|
||||
{
|
||||
var path = Path.Combine(nugetPath, reference.Name, reference.Version, "lib", reference.Framework, $"{reference.Name}.dll");
|
||||
if (!File.Exists(path))
|
||||
Utilities.RestoreNugetPackages(graph, target);
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(path));
|
||||
graph.AddCopyFile(dstFile, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
DeployFiles(graph, target, targetBuildOptions, outputPath);
|
||||
}
|
||||
|
||||
using (new ProfileEventScope("PostBuild"))
|
||||
@@ -301,10 +281,10 @@ namespace Flax.Build
|
||||
// Reference Nuget package
|
||||
if (buildData.TargetOptions.NugetPackageReferences.Any())
|
||||
{
|
||||
var nugetPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
||||
var nugetPath = Utilities.GetNugetPackagesPath();
|
||||
foreach (var reference in buildOptions.NugetPackageReferences)
|
||||
{
|
||||
var path = Path.Combine(nugetPath, reference.Name, reference.Version, "lib", reference.Framework, $"{reference.Name}.dll");
|
||||
var path = reference.GetLibPath(nugetPath);
|
||||
args.Add(string.Format("/reference:\"{0}\"", path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,11 @@ namespace Flax.Build.NativeCpp
|
||||
Version = version;
|
||||
Framework = framework;
|
||||
}
|
||||
|
||||
internal string GetLibPath(string nugetPath)
|
||||
{
|
||||
return Path.Combine(nugetPath, Name, Version, "lib", Framework, $"{Name}.dll");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -167,7 +172,7 @@ namespace Flax.Build.NativeCpp
|
||||
/// <summary>
|
||||
/// The nuget package references.
|
||||
/// </summary>
|
||||
public List<NugetPackage> NugetPackageReferences = new List<NugetPackage>();
|
||||
public HashSet<NugetPackage> NugetPackageReferences = new HashSet<NugetPackage>();
|
||||
|
||||
/// <summary>
|
||||
/// The collection of defines with preprocessing symbol for a source files of this module. Inherited by the modules that include it.
|
||||
|
||||
@@ -1057,27 +1057,7 @@ namespace Flax.Build
|
||||
// Deploy files
|
||||
if (!buildData.Target.IsPreBuilt)
|
||||
{
|
||||
using (new ProfileEventScope("DeployFiles"))
|
||||
{
|
||||
foreach (var srcFile in targetBuildOptions.OptionalDependencyFiles.Where(File.Exists).Union(targetBuildOptions.DependencyFiles))
|
||||
{
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(srcFile));
|
||||
graph.AddCopyFile(dstFile, srcFile);
|
||||
}
|
||||
|
||||
if (targetBuildOptions.NugetPackageReferences.Any())
|
||||
{
|
||||
var nugetPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
||||
foreach (var reference in targetBuildOptions.NugetPackageReferences)
|
||||
{
|
||||
var path = Path.Combine(nugetPath, reference.Name, reference.Version, "lib", reference.Framework, $"{reference.Name}.dll");
|
||||
if (!File.Exists(path))
|
||||
Utilities.RestoreNugetPackages(graph, target);
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(path));
|
||||
graph.AddCopyFile(dstFile, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
DeployFiles(graph, target, targetBuildOptions, outputPath);
|
||||
}
|
||||
|
||||
using (new ProfileEventScope("PostBuild"))
|
||||
@@ -1270,27 +1250,7 @@ namespace Flax.Build
|
||||
// Deploy files
|
||||
if (!buildData.Target.IsPreBuilt)
|
||||
{
|
||||
using (new ProfileEventScope("DeployFiles"))
|
||||
{
|
||||
foreach (var srcFile in targetBuildOptions.OptionalDependencyFiles.Where(File.Exists).Union(targetBuildOptions.DependencyFiles))
|
||||
{
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(srcFile));
|
||||
graph.AddCopyFile(dstFile, srcFile);
|
||||
}
|
||||
|
||||
if (targetBuildOptions.NugetPackageReferences.Any())
|
||||
{
|
||||
var nugetPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
||||
foreach (var reference in targetBuildOptions.NugetPackageReferences)
|
||||
{
|
||||
var path = Path.Combine(nugetPath, reference.Name, reference.Version, "lib", reference.Framework, $"{reference.Name}.dll");
|
||||
if (!File.Exists(path))
|
||||
Utilities.RestoreNugetPackages(graph, target);
|
||||
var dstFile = Path.Combine(outputPath, Path.GetFileName(path));
|
||||
graph.AddCopyFile(dstFile, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
DeployFiles(graph, target, targetBuildOptions, outputPath);
|
||||
}
|
||||
|
||||
using (new ProfileEventScope("PostBuild"))
|
||||
|
||||
@@ -42,21 +42,14 @@ namespace Flax.Build
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores a targets nuget packages.
|
||||
/// Gets the NuGet packages cache folder path.
|
||||
/// </summary>
|
||||
/// <param name="graph">The task graph.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <param name="dotNetPath">The dotnet path.</param>
|
||||
public static void RestoreNugetPackages(Graph.TaskGraph graph, Target target)
|
||||
/// <returns>The path.</returns>
|
||||
public static string GetNugetPackagesPath()
|
||||
{
|
||||
var dotNetPath = GetDotNetPath();
|
||||
var task = graph.Add<Graph.Task>();
|
||||
task.WorkingDirectory = target.FolderPath;
|
||||
task.InfoMessage = $"Restoring Nuget Packages for {target.Name}";
|
||||
task.CommandPath = dotNetPath;
|
||||
task.CommandArguments = $"restore";
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash code for the string (the same for all platforms). Matches Engine algorithm for string hashing.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user