Generate runtime graph when building runtime
This commit is contained in:
parent
1c9803d980
commit
77e511c4d4
6 changed files with 253 additions and 12 deletions
|
@ -74,20 +74,37 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
File.Move(Path.Combine(SharedFrameworkNameAndVersionRoot, "framework.deps"), Path.Combine(SharedFrameworkNameAndVersionRoot, $"{SharedFrameworkName}.deps"));
|
File.Move(Path.Combine(SharedFrameworkNameAndVersionRoot, "framework.deps"), Path.Combine(SharedFrameworkNameAndVersionRoot, $"{SharedFrameworkName}.deps"));
|
||||||
File.Move(Path.Combine(SharedFrameworkNameAndVersionRoot, "framework.deps.json"), destinationDeps);
|
File.Move(Path.Combine(SharedFrameworkNameAndVersionRoot, "framework.deps.json"), destinationDeps);
|
||||||
|
|
||||||
// Merge in the RID fallback graph
|
// Generate RID fallback graph
|
||||||
var fallbackFileName = PlatformServices.Default.Runtime.OperatingSystemPlatform.ToString().ToLowerInvariant() + ".json";
|
string runtimeGraphGeneratorRuntime = null;
|
||||||
var fallbackFile = Path.Combine(Dirs.RepoRoot, "src", "sharedframework", "rid-fallbacks", fallbackFileName);
|
switch (PlatformServices.Default.Runtime.OperatingSystemPlatform)
|
||||||
if (File.Exists(fallbackFile))
|
|
||||||
{
|
{
|
||||||
c.Info($"Merging in RID fallback graph: {fallbackFile}");
|
case Platform.Windows:
|
||||||
var deps = JObject.Parse(File.ReadAllText(destinationDeps));
|
runtimeGraphGeneratorRuntime = "win";
|
||||||
var ridfallback = JObject.Parse(File.ReadAllText(fallbackFile));
|
break;
|
||||||
deps["runtimes"] = ridfallback["runtimes"];
|
case Platform.Linux:
|
||||||
File.WriteAllText(destinationDeps, deps.ToString(Formatting.Indented));
|
runtimeGraphGeneratorRuntime = "linux";
|
||||||
|
break;
|
||||||
|
case Platform.Darwin:
|
||||||
|
runtimeGraphGeneratorRuntime = "osx";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(runtimeGraphGeneratorRuntime))
|
||||||
|
{
|
||||||
|
var runtimeGraphGeneratorName = "RuntimeGraphGenerator";
|
||||||
|
var runtimeGraphGeneratorProject = Path.Combine(c.BuildContext.BuildDirectory, "tools", runtimeGraphGeneratorName);
|
||||||
|
var runtimeGraphGeneratorOutput = Path.Combine(Dirs.Output, "tools", runtimeGraphGeneratorName);
|
||||||
|
|
||||||
|
DotNetCli.Stage2.Publish(
|
||||||
|
"--output", runtimeGraphGeneratorOutput,
|
||||||
|
runtimeGraphGeneratorProject).Execute().EnsureSuccessful();
|
||||||
|
var runtimeGraphGeneratorExe = Path.Combine(runtimeGraphGeneratorOutput, $"{runtimeGraphGeneratorName}{Constants.ExeSuffix}");
|
||||||
|
|
||||||
|
Cmd(runtimeGraphGeneratorExe, "--project", SharedFrameworkSourceRoot, "--deps", destinationDeps, runtimeGraphGeneratorRuntime)
|
||||||
|
.Execute();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.Warn($"RID fallback graph file not found: {fallbackFile}");
|
c.Error($"Could not determine rid graph generation runtime for platform {PlatformServices.Default.Runtime.OperatingSystemPlatform}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// corehost will be renamed to dotnet at some point and then we will not need to rename it here.
|
// corehost will be renamed to dotnet at some point and then we will not need to rename it here.
|
||||||
|
|
|
@ -1,19 +1,29 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
namespace Microsoft.Extensions.DependencyModel
|
||||||
{
|
{
|
||||||
public class RuntimeFallbacks
|
public class RuntimeFallbacks
|
||||||
{
|
{
|
||||||
public string Runtime { get; set; }
|
public string Runtime { get; set; }
|
||||||
public IEnumerable<string> Fallbacks { get; set; }
|
public IReadOnlyList<string> Fallbacks { get; set; }
|
||||||
|
|
||||||
public RuntimeFallbacks(string runtime, IEnumerable<string> fallbacks)
|
public RuntimeFallbacks(string runtime, IEnumerable<string> fallbacks)
|
||||||
{
|
{
|
||||||
|
if (runtime == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(runtime));
|
||||||
|
}
|
||||||
|
if (fallbacks == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(fallbacks));
|
||||||
|
}
|
||||||
Runtime = runtime;
|
Runtime = runtime;
|
||||||
Fallbacks = fallbacks;
|
Fallbacks = fallbacks.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
110
tools/RuntimeGraphGenerator/Program.cs
Normal file
110
tools/RuntimeGraphGenerator/Program.cs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.Extensions.DependencyModel;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
using NuGet.Packaging;
|
||||||
|
using NuGet.Versioning;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
|
|
||||||
|
namespace RuntimeGraphGenerator
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
DebugHelper.HandleDebugSwitch(ref args);
|
||||||
|
|
||||||
|
string projectDirectory = null;
|
||||||
|
string depsFile = null;
|
||||||
|
IReadOnlyList<string> runtimes = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ArgumentSyntax.Parse(args, syntax =>
|
||||||
|
{
|
||||||
|
syntax.ApplicationName = "Runtime GraphGenerator";
|
||||||
|
|
||||||
|
syntax.HandleHelp = false;
|
||||||
|
syntax.HandleErrors = false;
|
||||||
|
|
||||||
|
syntax.DefineOption("p|project", ref projectDirectory, "Project location");
|
||||||
|
syntax.DefineOption("d|deps", ref depsFile, "Deps file path");
|
||||||
|
|
||||||
|
syntax.DefineParameterList("runtimes", ref runtimes, "Runtimes");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (ArgumentSyntaxException exception)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine(exception.Message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtimes == null || runtimes.Count == 0)
|
||||||
|
{
|
||||||
|
Reporter.Error.WriteLine("No runtimes specified");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!File.Exists(depsFile))
|
||||||
|
{
|
||||||
|
Reporter.Error.WriteLine($"Deps file not found: {depsFile}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!Directory.Exists(projectDirectory))
|
||||||
|
{
|
||||||
|
Reporter.Error.WriteLine($"Project directory not found: {projectDirectory}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DependencyContext context;
|
||||||
|
using (var depsStream = File.OpenRead(depsFile))
|
||||||
|
{
|
||||||
|
context = new DependencyContextJsonReader().Read(depsStream);
|
||||||
|
}
|
||||||
|
var framework = NuGetFramework.Parse(context.TargetFramework);
|
||||||
|
var projectContext = ProjectContext.Create(projectDirectory, framework);
|
||||||
|
|
||||||
|
// Configuration is used only for P2P dependencies so were don't care
|
||||||
|
var exporter = projectContext.CreateExporter("Debug");
|
||||||
|
var manager = new RuntimeGraphManager();
|
||||||
|
var graph = manager.Collect(exporter.GetDependencies(LibraryType.Package));
|
||||||
|
var expandedGraph = manager.Expand(graph, runtimes);
|
||||||
|
|
||||||
|
context = new DependencyContext(
|
||||||
|
context.TargetFramework,
|
||||||
|
context.Runtime,
|
||||||
|
context.IsPortable,
|
||||||
|
context.CompilationOptions,
|
||||||
|
context.CompileLibraries,
|
||||||
|
context.RuntimeLibraries,
|
||||||
|
expandedGraph
|
||||||
|
);
|
||||||
|
|
||||||
|
using (var depsStream = File.Create(depsFile))
|
||||||
|
{
|
||||||
|
new DependencyContextWriter().Write(context, depsStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Reporter.Error.WriteLine(ex.ToString());
|
||||||
|
#else
|
||||||
|
Reporter.Error.WriteLine(ex.Message);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
tools/RuntimeGraphGenerator/RuntimeGraphGenerator.xproj
Normal file
19
tools/RuntimeGraphGenerator/RuntimeGraphGenerator.xproj
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0.25029" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25029</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>efc4fe68-83eb-40e4-bfa8-61d0b4626f25</ProjectGuid>
|
||||||
|
<RootNamespace>RuntimeGraphGenerator</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
60
tools/RuntimeGraphGenerator/RuntimeGraphManager.cs
Normal file
60
tools/RuntimeGraphGenerator/RuntimeGraphManager.cs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
|
using NuGet.RuntimeModel;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.Extensions.DependencyModel;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectModel
|
||||||
|
{
|
||||||
|
public class RuntimeGraphManager
|
||||||
|
{
|
||||||
|
private const string RuntimeJsonFileName = "runtime.json";
|
||||||
|
|
||||||
|
public NuGet.RuntimeModel.RuntimeGraph Collect(IEnumerable<LibraryExport> exports)
|
||||||
|
{
|
||||||
|
var graph = RuntimeGraph.Empty;
|
||||||
|
foreach (var export in exports)
|
||||||
|
{
|
||||||
|
if (export.Library.Identity.Type == LibraryType.Package)
|
||||||
|
{
|
||||||
|
var runtimeJson = ((PackageDescription) export.Library).Library.Files.FirstOrDefault(f => f == RuntimeJsonFileName);
|
||||||
|
if (runtimeJson != null)
|
||||||
|
{
|
||||||
|
var runtimeJsonFullName = Path.Combine(export.Library.Path, runtimeJson);
|
||||||
|
graph = RuntimeGraph.Merge(graph, JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonFullName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<RuntimeFallbacks> Expand(RuntimeGraph runtimeGraph, IEnumerable<string> runtimes)
|
||||||
|
{
|
||||||
|
foreach (var runtime in runtimes)
|
||||||
|
{
|
||||||
|
var importers = FindImporters(runtimeGraph, runtime);
|
||||||
|
foreach (var importer in importers)
|
||||||
|
{
|
||||||
|
// ExpandRuntime return runtime itself as first item so we are skiping it
|
||||||
|
yield return new RuntimeFallbacks(importer, runtimeGraph.ExpandRuntime(importer).Skip(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<string> FindImporters(RuntimeGraph runtimeGraph, string runtime)
|
||||||
|
{
|
||||||
|
foreach (var runtimePair in runtimeGraph.Runtimes)
|
||||||
|
{
|
||||||
|
var expanded = runtimeGraph.ExpandRuntime(runtimePair.Key);
|
||||||
|
if (expanded.Contains(runtime))
|
||||||
|
{
|
||||||
|
yield return runtimePair.Key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
tools/RuntimeGraphGenerator/project.json
Normal file
25
tools/RuntimeGraphGenerator/project.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"compilationOptions": {
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.RuntimeModel": "3.4.0-rtm-0763",
|
||||||
|
"NuGet.Versioning": "3.4.0-rtm-0763",
|
||||||
|
"System.CommandLine": "0.1.0-e160119-1",
|
||||||
|
"System.Runtime.Serialization.Json": "1.0.0-rc2-23911",
|
||||||
|
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
|
||||||
|
"Microsoft.DotNet.Cli.Utils": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537",
|
||||||
|
"Microsoft.NETCore.ConsoleHost": "1.0.0-rc2-23911",
|
||||||
|
"NETStandard.Library": "1.5.0-rc2-23911"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netstandardapp1.5": {
|
||||||
|
"imports": [
|
||||||
|
"dnxcore50",
|
||||||
|
"portable-net45+wp80+win8+wpa81+dnxcore50"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue