Add compilation options to dependency context
This commit is contained in:
parent
697e99ea6e
commit
e39d30ba9c
8 changed files with 223 additions and 30 deletions
|
@ -5,49 +5,99 @@ using System.Threading.Tasks;
|
|||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||
using Microsoft.DotNet.ProjectModel.Graph;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyModel
|
||||
{
|
||||
public static class DependencyContextBuilder
|
||||
{
|
||||
public static DependencyContext FromLibraryExporter(LibraryExporter libraryExporter, string target, string runtime)
|
||||
public static DependencyContext Build(CommonCompilerOptions compilerOptions, LibraryExporter libraryExporter, string configuration, NuGetFramework target, string runtime)
|
||||
{
|
||||
var dependencies = libraryExporter.GetAllExports();
|
||||
var dependencies = libraryExporter.GetAllExports().Where(export => export.Library.Framework.Equals(target)).ToList();
|
||||
|
||||
return new DependencyContext(target, runtime,
|
||||
GetLibraries(dependencies, export => export.CompilationAssemblies),
|
||||
GetLibraries(dependencies, export => export.RuntimeAssemblies));
|
||||
// Sometimes we have package and reference assembly with the same name (System.Runtime for example) thats why we
|
||||
// deduplicating them prefering reference assembly
|
||||
var dependencyLookup = dependencies
|
||||
.OrderBy(export => export.Library.Identity.Type == LibraryType.ReferenceAssembly)
|
||||
.GroupBy(export => export.Library.Identity.Name)
|
||||
.Select(exports => exports.First())
|
||||
.Select(export => new Dependency(export.Library.Identity.Name, export.Library.Identity.Version.ToString()))
|
||||
.ToDictionary(dependency => dependency.Name);
|
||||
|
||||
return new DependencyContext(target.DotNetFrameworkName, runtime,
|
||||
GetCompilationOptions(compilerOptions),
|
||||
GetLibraries(dependencies, dependencyLookup, target, configuration, export => export.CompilationAssemblies),
|
||||
GetLibraries(dependencies, dependencyLookup, target, configuration, export => export.RuntimeAssemblies));
|
||||
}
|
||||
|
||||
private static Library[] GetLibraries(IEnumerable<LibraryExport> dependencies, Func<LibraryExport, IEnumerable<LibraryAsset>> assemblySelector)
|
||||
private static CompilationOptions GetCompilationOptions(CommonCompilerOptions compilerOptions)
|
||||
{
|
||||
return dependencies.Select(export => GetLibrary(export, assemblySelector(export), dependencies)).ToArray();
|
||||
return new CompilationOptions(compilerOptions.Defines,
|
||||
compilerOptions.LanguageVersion,
|
||||
compilerOptions.Platform,
|
||||
compilerOptions.AllowUnsafe,
|
||||
compilerOptions.WarningsAsErrors,
|
||||
compilerOptions.Optimize,
|
||||
compilerOptions.KeyFile,
|
||||
compilerOptions.DelaySign,
|
||||
compilerOptions.PublicSign,
|
||||
compilerOptions.EmitEntryPoint);
|
||||
}
|
||||
|
||||
private static Library GetLibrary(LibraryExport export, IEnumerable<LibraryAsset> libraryAssets, IEnumerable<LibraryExport> dependencies)
|
||||
private static Library[] GetLibraries(IEnumerable<LibraryExport> dependencies,
|
||||
IDictionary<string, Dependency> dependencyLookup,
|
||||
NuGetFramework target,
|
||||
string configuration,
|
||||
Func<LibraryExport, IEnumerable<LibraryAsset>> assemblySelector)
|
||||
{
|
||||
return dependencies.Select(export => GetLibrary(export, target, configuration, assemblySelector(export), dependencyLookup)).ToArray();
|
||||
}
|
||||
|
||||
private static Library GetLibrary(LibraryExport export,
|
||||
NuGetFramework target,
|
||||
string configuration,
|
||||
IEnumerable<LibraryAsset> libraryAssets,
|
||||
IDictionary<string, Dependency> dependencyLookup)
|
||||
{
|
||||
var type = export.Library.Identity.Type.Value.ToLowerInvariant();
|
||||
|
||||
var serviceable = (export.Library as PackageDescription)?.Library.IsServiceable ?? false;
|
||||
var version = dependencies.Where(dependency => dependency.Library.Identity == export.Library.Identity);
|
||||
var libraryDependencies = new List<Dependency>();
|
||||
|
||||
var libraryDependencies = export.Library.Dependencies.Select(libraryRange => GetDependency(libraryRange, dependencies)).ToArray();
|
||||
foreach (var libraryDependency in export.Library.Dependencies)
|
||||
{
|
||||
Dependency dependency;
|
||||
if (dependencyLookup.TryGetValue(libraryDependency.Name, out dependency))
|
||||
{
|
||||
libraryDependencies.Add(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
string[] assemblies;
|
||||
if (type == "project")
|
||||
{
|
||||
var isExe = ((ProjectDescription) export.Library)
|
||||
.Project
|
||||
.GetCompilerOptions(target, configuration)
|
||||
.EmitEntryPoint
|
||||
.GetValueOrDefault(false);
|
||||
|
||||
assemblies = new[] { export.Library.Identity.Name + (isExe ? ".exe": ".dll") };
|
||||
}
|
||||
else
|
||||
{
|
||||
assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath).ToArray();
|
||||
}
|
||||
|
||||
return new Library(
|
||||
export.Library.Identity.Type.ToString().ToLowerInvariant(),
|
||||
type,
|
||||
export.Library.Identity.Name,
|
||||
export.Library.Identity.Version.ToString(),
|
||||
export.Library.Hash,
|
||||
libraryAssets.Select(libraryAsset => libraryAsset.RelativePath).ToArray(),
|
||||
libraryDependencies,
|
||||
assemblies,
|
||||
libraryDependencies.ToArray(),
|
||||
serviceable
|
||||
);
|
||||
}
|
||||
|
||||
private static Dependency GetDependency(LibraryRange libraryRange, IEnumerable<LibraryExport> dependencies)
|
||||
{
|
||||
var version =
|
||||
dependencies.First(d => d.Library.Identity.Name == libraryRange.Name)
|
||||
.Library.Identity.Version.ToString();
|
||||
return new Dependency(libraryRange.Name, version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,8 +255,11 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
if (compilationOptions.PreserveCompilationContext == true)
|
||||
{
|
||||
var dependencyContext = DependencyContextBuilder.FromLibraryExporter(
|
||||
libraryExporter, context.TargetFramework.DotNetFrameworkName, context.RuntimeIdentifier);
|
||||
var dependencyContext = DependencyContextBuilder.Build(compilationOptions,
|
||||
libraryExporter,
|
||||
args.ConfigValue,
|
||||
context.TargetFramework,
|
||||
context.RuntimeIdentifier);
|
||||
|
||||
var writer = new DependencyContextWriter();
|
||||
var depsJsonFile = Path.Combine(intermediateOutputPath, context.ProjectFile.Name + "dotnet-compile.deps.json");
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyModel
|
||||
{
|
||||
public class CompilationOptions
|
||||
{
|
||||
public IEnumerable<string> Defines { get; }
|
||||
|
||||
public string LanguageVersion { get; }
|
||||
|
||||
public string Platform { get; }
|
||||
|
||||
public bool? AllowUnsafe { get; }
|
||||
|
||||
public bool? WarningsAsErrors { get; }
|
||||
|
||||
public bool? Optimize { get; }
|
||||
|
||||
public string KeyFile { get; }
|
||||
|
||||
public bool? DelaySign { get; }
|
||||
|
||||
public bool? PublicSign { get; }
|
||||
|
||||
public bool? EmitEntryPoint { get; }
|
||||
|
||||
public CompilationOptions(IEnumerable<string> defines,
|
||||
string languageVersion,
|
||||
string platform,
|
||||
bool? allowUnsafe,
|
||||
bool? warningsAsErrors,
|
||||
bool? optimize,
|
||||
string keyFile,
|
||||
bool? delaySign,
|
||||
bool? publicSign,
|
||||
bool? emitEntryPoint)
|
||||
{
|
||||
Defines = defines;
|
||||
LanguageVersion = languageVersion;
|
||||
Platform = platform;
|
||||
AllowUnsafe = allowUnsafe;
|
||||
WarningsAsErrors = warningsAsErrors;
|
||||
Optimize = optimize;
|
||||
KeyFile = keyFile;
|
||||
DelaySign = delaySign;
|
||||
PublicSign = publicSign;
|
||||
EmitEntryPoint = emitEntryPoint;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,17 +12,20 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
{
|
||||
private const string DepsResourceSufix = ".deps.json";
|
||||
|
||||
public DependencyContext(string target, string runtime, Library[] compileLibraries, Library[] runtimeLibraries)
|
||||
public DependencyContext(string target, string runtime, CompilationOptions compilationOptions, Library[] compileLibraries, Library[] runtimeLibraries)
|
||||
{
|
||||
Target = target;
|
||||
Runtime = runtime;
|
||||
CompilationOptions = compilationOptions;
|
||||
CompileLibraries = compileLibraries;
|
||||
RuntimeLibraries = runtimeLibraries;
|
||||
}
|
||||
|
||||
public string Target { get; set; }
|
||||
public string Target { get; }
|
||||
|
||||
public string Runtime { get; set; }
|
||||
public string Runtime { get; }
|
||||
|
||||
public CompilationOptions CompilationOptions { get; }
|
||||
|
||||
public IReadOnlyList<Library> CompileLibraries { get; }
|
||||
|
||||
|
|
|
@ -37,11 +37,28 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
return new DependencyContext(
|
||||
compileTargetProperty.Key,
|
||||
runtimeTargetProperty.Key.Substring(compileTargetProperty.Key.Length + 1),
|
||||
ReadCompilationOptions((JObject)root[DependencyContextStrings.CompilationOptionsPropertName]),
|
||||
ReadLibraries((JObject)runtimeTargetProperty.Value, true, libraryStubs),
|
||||
ReadLibraries((JObject)compileTargetProperty.Value, false, libraryStubs)
|
||||
);
|
||||
}
|
||||
|
||||
private CompilationOptions ReadCompilationOptions(JObject compilationOptionsObject)
|
||||
{
|
||||
return new CompilationOptions(
|
||||
compilationOptionsObject[DependencyContextStrings.DefinesPropertyName]?.Values<string>(),
|
||||
compilationOptionsObject[DependencyContextStrings.LanguageVersionPropertyName]?.Value<string>(),
|
||||
compilationOptionsObject[DependencyContextStrings.PlatformPropertyName]?.Value<string>(),
|
||||
compilationOptionsObject[DependencyContextStrings.AllowUnsafePropertyName]?.Value<bool>(),
|
||||
compilationOptionsObject[DependencyContextStrings.WarningsAsErrorsPropertyName]?.Value<bool>(),
|
||||
compilationOptionsObject[DependencyContextStrings.OptimizePropertyName]?.Value<bool>(),
|
||||
compilationOptionsObject[DependencyContextStrings.KeyFilePropertyName]?.Value<string>(),
|
||||
compilationOptionsObject[DependencyContextStrings.DelaySignPropertyName]?.Value<bool>(),
|
||||
compilationOptionsObject[DependencyContextStrings.PublicSignPropertyName]?.Value<bool>(),
|
||||
compilationOptionsObject[DependencyContextStrings.EmitEntryPointPropertyName]?.Value<bool>()
|
||||
);
|
||||
}
|
||||
|
||||
private Library[] ReadLibraries(JObject librariesObject, bool runtime, Dictionary<string, DependencyContextReader.LibraryStub> libraryStubs)
|
||||
{
|
||||
return librariesObject.Properties().Select(property => ReadLibrary(property, runtime, libraryStubs)).ToArray();
|
||||
|
@ -50,7 +67,7 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
private Library ReadLibrary(JProperty property, bool runtime, Dictionary<string, DependencyContextReader.LibraryStub> libraryStubs)
|
||||
{
|
||||
var nameWithVersion = property.Name;
|
||||
DependencyContextReader.LibraryStub stub;
|
||||
LibraryStub stub;
|
||||
|
||||
if (!libraryStubs.TryGetValue(nameWithVersion, out stub))
|
||||
{
|
||||
|
|
|
@ -19,5 +19,27 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
internal const string TypePropertyName = "type";
|
||||
|
||||
internal const string ServiceablePropertyName = "serviceable";
|
||||
|
||||
internal const string CompilationOptionsPropertName = "compilationOptions";
|
||||
|
||||
internal const string DefinesPropertyName = "defines";
|
||||
|
||||
internal const string LanguageVersionPropertyName = "languageVersion";
|
||||
|
||||
internal const string PlatformPropertyName = "platform";
|
||||
|
||||
internal const string AllowUnsafePropertyName = "allowUnsafe";
|
||||
|
||||
internal const string WarningsAsErrorsPropertyName = "warningsAsErrors";
|
||||
|
||||
internal const string OptimizePropertyName = "optimize";
|
||||
|
||||
internal const string KeyFilePropertyName = "keyFile";
|
||||
|
||||
internal const string DelaySignPropertyName = "delaySign";
|
||||
|
||||
internal const string PublicSignPropertyName = "publicSign";
|
||||
|
||||
internal const string EmitEntryPointPropertyName = "emitEntryPoint";
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -22,10 +23,56 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
private JObject Write(DependencyContext context)
|
||||
{
|
||||
return new JObject(
|
||||
new JProperty(DependencyContextStrings.CompilationOptionsPropertName, WriteCompilationOptions(context.CompilationOptions)),
|
||||
new JProperty(DependencyContextStrings.TargetsPropertyName, WriteTargets(context)),
|
||||
new JProperty(DependencyContextStrings.LibrariesPropertyName, WriteLibraries(context))
|
||||
);
|
||||
}
|
||||
|
||||
private JObject WriteCompilationOptions(CompilationOptions compilationOptions)
|
||||
{
|
||||
var o = new JObject();
|
||||
if (compilationOptions.Defines != null)
|
||||
{
|
||||
o[DependencyContextStrings.DefinesPropertyName] = new JArray(compilationOptions.Defines);
|
||||
}
|
||||
if (compilationOptions.LanguageVersion != null)
|
||||
{
|
||||
o[DependencyContextStrings.LanguageVersionPropertyName] = compilationOptions.LanguageVersion;
|
||||
}
|
||||
if (compilationOptions.Platform != null)
|
||||
{
|
||||
o[DependencyContextStrings.PlatformPropertyName] = compilationOptions.Platform;
|
||||
}
|
||||
if (compilationOptions.AllowUnsafe != null)
|
||||
{
|
||||
o[DependencyContextStrings.AllowUnsafePropertyName] = compilationOptions.AllowUnsafe;
|
||||
}
|
||||
if (compilationOptions.WarningsAsErrors != null)
|
||||
{
|
||||
o[DependencyContextStrings.WarningsAsErrorsPropertyName] = compilationOptions.WarningsAsErrors;
|
||||
}
|
||||
if (compilationOptions.Optimize != null)
|
||||
{
|
||||
o[DependencyContextStrings.OptimizePropertyName] = compilationOptions.Optimize;
|
||||
}
|
||||
if (compilationOptions.KeyFile != null)
|
||||
{
|
||||
o[DependencyContextStrings.KeyFilePropertyName] = compilationOptions.KeyFile;
|
||||
}
|
||||
if (compilationOptions.DelaySign != null)
|
||||
{
|
||||
o[DependencyContextStrings.DelaySignPropertyName] = compilationOptions.DelaySign;
|
||||
}
|
||||
if (compilationOptions.PublicSign != null)
|
||||
{
|
||||
o[DependencyContextStrings.PublicSignPropertyName] = compilationOptions.PublicSign;
|
||||
}
|
||||
if (compilationOptions.EmitEntryPoint != null)
|
||||
{
|
||||
o[DependencyContextStrings.EmitEntryPointPropertyName] = compilationOptions.EmitEntryPoint;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
private JObject WriteTargets(DependencyContext context)
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
"Newtonsoft.Json": "7.0.1"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnx451": {},
|
||||
"dnxcore50": {
|
||||
"net451": { },
|
||||
"dotnet5.4": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.0.21-rc2-23618",
|
||||
"System.Linq": "4.0.1-rc2-23616",
|
||||
"System.Runtime": "4.0.21-rc2-23616",
|
||||
"System.Dynamic.Runtime": "4.0.11-rc2-23616"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue