Fix deploying NuGet packages to include dependencies (recursive)

#3900
This commit is contained in:
Wojtek Figat
2026-01-22 23:39:38 +01:00
parent 6dbfd25bdb
commit b09fbe2d9b
2 changed files with 74 additions and 12 deletions

View File

@@ -440,6 +440,7 @@ namespace Flax.Build
{
// Find all packages to deploy (incl. dependencies) and restore if needed
var nugetPath = Utilities.GetNugetPackagesPath();
Log.Verbose($"Deploying NuGet packages from {nugetPath}");
var restoreOnce = true;
var nugetFiles = new HashSet<string>();
foreach (var reference in targetBuildOptions.NugetPackageReferences)
@@ -452,17 +453,7 @@ namespace Flax.Build
restoreOnce = false;
}
// Deploy library
var path = reference.GetLibPath(nugetPath, folder);
nugetFiles.Add(path);
// Copy additional files (if included)
path = Path.ChangeExtension(path, "xml");
if (File.Exists(path))
nugetFiles.Add(path);
path = Path.ChangeExtension(path, "pdb");
if (targetBuildOptions.Configuration != TargetConfiguration.Release && File.Exists(path))
nugetFiles.Add(path);
DeployNuGetPackage(nugetPath, targetBuildOptions, nugetFiles, reference, folder);
}
// Copy libraries from all referenced packages to the output folder
@@ -505,5 +496,49 @@ namespace Flax.Build
Log.Info($"Restoring NuGet packages for target {target.Name}");
Utilities.Run(Utilities.GetDotNetPath(), $"restore \"{csprojPath}\"", null, null, Utilities.RunOptions.DefaultTool);
}
private static void DeployNuGetPackage(string nugetPath, BuildOptions targetBuildOptions, HashSet<string> nugetFiles, NugetPackage package, string folder = null)
{
// Deploy library
var path = package.GetLibPath(nugetPath, folder);
if (!File.Exists(path))
return;
Log.Verbose($"Deploying NuGet package {package.Name}, {package.Version}, {package.Framework}");
nugetFiles.Add(path);
// Copy additional files (if included)
path = Path.ChangeExtension(path, "xml");
if (File.Exists(path))
nugetFiles.Add(path);
path = Path.ChangeExtension(path, "pdb");
if (targetBuildOptions.Configuration != TargetConfiguration.Release && File.Exists(path))
nugetFiles.Add(path);
// Read package dependencies
var nuspecFile = package.GetNuspecPath(nugetPath);
if (File.Exists(nuspecFile))
{
var doc = System.Xml.Linq.XDocument.Load(nuspecFile);
var root = (System.Xml.Linq.XElement)doc.FirstNode;
var metadataNode = root.Descendants().First(x => x.Name.LocalName== "metadata");
var dependenciesNode = metadataNode.Descendants().First(x => x.Name.LocalName == "dependencies");
var groupNode = dependenciesNode.Descendants().FirstOrDefault(x => x.Attribute("targetFramework")?.Value == package.Framework);
if (groupNode == null)
{
Log.Warning($"Cannot find framework {package.Framework} inside NuGet package {package.Name}, {package.Version}");
return;
}
foreach (var dependency in groupNode.Descendants())
{
if (dependency.Name.LocalName != "dependency")
continue;
// Deploy dependency package
var dependencyId = dependency.Attribute("id").Value;
var dependencyVersion = dependency.Attribute("version").Value;
DeployNuGetPackage(nugetPath, targetBuildOptions, nugetFiles, new NugetPackage { Name = dependencyId, Version = dependencyVersion, Framework = package.Framework } );
}
}
}
}
}

View File

@@ -105,7 +105,34 @@ namespace Flax.Build.NativeCpp
internal string GetLibFolder(string nugetPath)
{
return Path.Combine(nugetPath, Name, Version, "lib", Framework);
var libFolder = Path.Combine(nugetPath, Name, Version, "lib", Framework);
if (Directory.Exists(libFolder))
return libFolder;
// Try to find nearest framework folder
if (Framework.StartsWith("net"))
{
var baseVersion = int.Parse(Framework.Substring(3, Framework.IndexOf('.') - 3));
for (int version = baseVersion - 1; version >= 5; version--)
{
var framework = $"net{version}.0";
libFolder = Path.Combine(nugetPath, Name, Version, "lib", framework);
if (Directory.Exists(libFolder))
{
Framework = framework;
return libFolder;
}
}
}
Log.Error($"Missing NuGet package \"{Name}, {Version}, {Framework}\" (nuget: {nugetPath})");
return string.Empty;
}
internal string GetNuspecPath(string nugetPath)
{
var files = Directory.GetFiles(Path.Combine(nugetPath, Name, Version), "*.nuspec", SearchOption.TopDirectoryOnly);
return files[0];
}
internal string GetLibPath(string nugetPath, string libFolder = null)