Added support for relocating reference assemblies
- This enables building for mono by setting the DOTNET_REFERENCE_ASSEMBLIES_PATH env variable. We could add some smart defaults for mono later. - Added a new diagnostic for reference assemblies when the framework itself isn't installed. - Added new error codes for dotnet.
This commit is contained in:
parent
3b9cfb086c
commit
80beccdbdc
6 changed files with 99 additions and 41 deletions
src/Microsoft.Extensions.ProjectModel
11
src/Microsoft.Extensions.ProjectModel/ErrorCodes.DotNet.cs
Normal file
11
src/Microsoft.Extensions.ProjectModel/ErrorCodes.DotNet.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
namespace Microsoft.Extensions.ProjectModel
|
||||||
|
{
|
||||||
|
public static partial class ErrorCodes
|
||||||
|
{
|
||||||
|
// Target framework not installed
|
||||||
|
public static readonly string DOTNET1011 = nameof(DOTNET1011);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace Microsoft.Extensions.ProjectModel
|
namespace Microsoft.Extensions.ProjectModel
|
||||||
{
|
{
|
||||||
public static class ErrorCodes
|
public static partial class ErrorCodes
|
||||||
{
|
{
|
||||||
// The dependency A could not be resolved.
|
// The dependency A could not be resolved.
|
||||||
public static readonly string NU1001 = nameof(NU1001);
|
public static readonly string NU1001 = nameof(NU1001);
|
|
@ -1,7 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.Extensions.Internal;
|
using Microsoft.Extensions.Internal;
|
||||||
using Microsoft.Extensions.ProjectModel.Graph;
|
using Microsoft.Extensions.ProjectModel.Graph;
|
||||||
using Microsoft.Extensions.ProjectModel.Resolution;
|
using Microsoft.Extensions.ProjectModel.Resolution;
|
||||||
|
@ -26,6 +27,8 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
public string ProjectDirectory { get; set; }
|
public string ProjectDirectory { get; set; }
|
||||||
|
|
||||||
public string PackagesDirectory { get; set; }
|
public string PackagesDirectory { get; set; }
|
||||||
|
|
||||||
|
public string ReferenceAssembliesPath { get; set; }
|
||||||
|
|
||||||
public ProjectContext Build()
|
public ProjectContext Build()
|
||||||
{
|
{
|
||||||
|
@ -44,6 +47,7 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
|
|
||||||
RootDirectory = GlobalSettings?.DirectoryPath ?? RootDirectory;
|
RootDirectory = GlobalSettings?.DirectoryPath ?? RootDirectory;
|
||||||
PackagesDirectory = PackagesDirectory ?? PackageDependencyProvider.ResolveRepositoryPath(RootDirectory, GlobalSettings);
|
PackagesDirectory = PackagesDirectory ?? PackageDependencyProvider.ResolveRepositoryPath(RootDirectory, GlobalSettings);
|
||||||
|
ReferenceAssembliesPath = ReferenceAssembliesPath ?? GetDefaultReferenceAssembliesPath();
|
||||||
|
|
||||||
LockFileLookup lockFileLookup = null;
|
LockFileLookup lockFileLookup = null;
|
||||||
|
|
||||||
|
@ -85,11 +89,12 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var frameworkReferenceResolver = new FrameworkReferenceResolver();
|
var frameworkReferenceResolver = new FrameworkReferenceResolver(ReferenceAssembliesPath);
|
||||||
var referenceAssemblyDependencyResolver = new ReferenceAssemblyDependencyResolver(frameworkReferenceResolver);
|
var referenceAssemblyDependencyResolver = new ReferenceAssemblyDependencyResolver(frameworkReferenceResolver);
|
||||||
|
bool requiresFrameworkAssemblies;
|
||||||
|
|
||||||
// Resolve the dependencies
|
// Resolve the dependencies
|
||||||
ResolveDependencies(libraries, referenceAssemblyDependencyResolver);
|
ResolveDependencies(libraries, referenceAssemblyDependencyResolver, out requiresFrameworkAssemblies);
|
||||||
|
|
||||||
var diagnostics = new List<DiagnosticMessage>();
|
var diagnostics = new List<DiagnosticMessage>();
|
||||||
|
|
||||||
|
@ -112,6 +117,22 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
DiagnosticMessageSeverity.Warning));
|
DiagnosticMessageSeverity.Warning));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requiresFrameworkAssemblies && !frameworkReferenceResolver.IsInstalled(TargetFramework))
|
||||||
|
{
|
||||||
|
var frameworkInfo = Project.GetTargetFramework(TargetFramework);
|
||||||
|
|
||||||
|
// If there was an attempt to use reference assemblies but they were not installed
|
||||||
|
// report an error
|
||||||
|
diagnostics.Add(new DiagnosticMessage(
|
||||||
|
ErrorCodes.DOTNET1011,
|
||||||
|
$"Framework not installed: {TargetFramework.DotNetFrameworkName}",
|
||||||
|
filePath: Project.ProjectFilePath,
|
||||||
|
severity: DiagnosticMessageSeverity.Error,
|
||||||
|
startLine: frameworkInfo.Line,
|
||||||
|
startColumn: frameworkInfo.Column
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// Create a library manager
|
// Create a library manager
|
||||||
var libraryManager = new LibraryManager(libraries.Values.ToList(), diagnostics);
|
var libraryManager = new LibraryManager(libraries.Values.ToList(), diagnostics);
|
||||||
|
|
||||||
|
@ -124,8 +145,12 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
libraryManager);
|
libraryManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResolveDependencies(Dictionary<LibraryKey, LibraryDescription> libraries, ReferenceAssemblyDependencyResolver referenceAssemblyDependencyResolver)
|
private void ResolveDependencies(Dictionary<LibraryKey, LibraryDescription> libraries,
|
||||||
|
ReferenceAssemblyDependencyResolver referenceAssemblyDependencyResolver,
|
||||||
|
out bool requiresFrameworkAssemblies)
|
||||||
{
|
{
|
||||||
|
requiresFrameworkAssemblies = false;
|
||||||
|
|
||||||
foreach (var library in libraries.Values.ToList())
|
foreach (var library in libraries.Values.ToList())
|
||||||
{
|
{
|
||||||
if (Equals(library.Identity.Type, LibraryType.Package) &&
|
if (Equals(library.Identity.Type, LibraryType.Package) &&
|
||||||
|
@ -146,6 +171,8 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
{
|
{
|
||||||
if (Equals(LibraryType.ReferenceAssembly, dependency.Target))
|
if (Equals(LibraryType.ReferenceAssembly, dependency.Target))
|
||||||
{
|
{
|
||||||
|
requiresFrameworkAssemblies = true;
|
||||||
|
|
||||||
dep = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ??
|
dep = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ??
|
||||||
UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||||
|
|
||||||
|
@ -203,6 +230,44 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetDefaultReferenceAssembliesPath()
|
||||||
|
{
|
||||||
|
// Allow setting the reference assemblies path via an environment variable
|
||||||
|
var referenceAssembliesPath = Environment.GetEnvironmentVariable("DOTNET_REFERENCE_ASSEMBLIES_PATH");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(referenceAssembliesPath))
|
||||||
|
{
|
||||||
|
return referenceAssembliesPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
// There is no reference assemblies path outside of windows
|
||||||
|
// The enviorment variable can be used to specify one
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// References assemblies are in %ProgramFiles(x86)% on
|
||||||
|
// 64 bit machines
|
||||||
|
var programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(programFiles))
|
||||||
|
{
|
||||||
|
// On 32 bit machines they are in %ProgramFiles%
|
||||||
|
programFiles = Environment.GetEnvironmentVariable("ProgramFiles");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(programFiles))
|
||||||
|
{
|
||||||
|
// Reference assemblies aren't installed
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Path.Combine(
|
||||||
|
programFiles,
|
||||||
|
"Reference Assemblies", "Microsoft", "Framework");
|
||||||
|
}
|
||||||
|
|
||||||
private void EnsureProjectLoaded()
|
private void EnsureProjectLoaded()
|
||||||
{
|
{
|
||||||
if (Project == null)
|
if (Project == null)
|
||||||
|
|
|
@ -465,7 +465,9 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
{
|
{
|
||||||
FrameworkName = frameworkName,
|
FrameworkName = frameworkName,
|
||||||
Dependencies = new List<LibraryRange>(),
|
Dependencies = new List<LibraryRange>(),
|
||||||
CompilerOptions = compilerOptions
|
CompilerOptions = compilerOptions,
|
||||||
|
Line = frameworkValue.Line,
|
||||||
|
Column = frameworkValue.Column
|
||||||
};
|
};
|
||||||
|
|
||||||
var frameworkDependencies = new List<LibraryRange>();
|
var frameworkDependencies = new List<LibraryRange>();
|
||||||
|
|
|
@ -14,8 +14,6 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
{
|
{
|
||||||
public class FrameworkReferenceResolver
|
public class FrameworkReferenceResolver
|
||||||
{
|
{
|
||||||
// TODO(anurse): Move the Mono stuff back in.
|
|
||||||
|
|
||||||
// FrameworkConstants doesn't have dnx46 yet
|
// FrameworkConstants doesn't have dnx46 yet
|
||||||
private static readonly NuGetFramework Dnx46 = new NuGetFramework(
|
private static readonly NuGetFramework Dnx46 = new NuGetFramework(
|
||||||
FrameworkConstants.FrameworkIdentifiers.Dnx,
|
FrameworkConstants.FrameworkIdentifiers.Dnx,
|
||||||
|
@ -28,6 +26,13 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
{ FrameworkConstants.CommonFrameworks.Dnx451, new [] { FrameworkConstants.CommonFrameworks.Net451 } },
|
{ FrameworkConstants.CommonFrameworks.Dnx451, new [] { FrameworkConstants.CommonFrameworks.Net451 } },
|
||||||
{ Dnx46, new [] { FrameworkConstants.CommonFrameworks.Net46 } }
|
{ Dnx46, new [] { FrameworkConstants.CommonFrameworks.Net46 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public FrameworkReferenceResolver(string referenceAssembliesPath)
|
||||||
|
{
|
||||||
|
ReferenceAssembliesPath = referenceAssembliesPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReferenceAssembliesPath { get; }
|
||||||
|
|
||||||
public bool TryGetAssembly(string name, NuGetFramework targetFramework, out string path, out Version version)
|
public bool TryGetAssembly(string name, NuGetFramework targetFramework, out string path, out Version version)
|
||||||
{
|
{
|
||||||
|
@ -65,15 +70,11 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
return !string.IsNullOrEmpty(path);
|
return !string.IsNullOrEmpty(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetAttemptedPaths(NuGetFramework targetFramework)
|
public bool IsInstalled(NuGetFramework targetFramework)
|
||||||
{
|
{
|
||||||
var information = _cache.GetOrAdd(targetFramework, GetFrameworkInformation);
|
var information = _cache.GetOrAdd(targetFramework, GetFrameworkInformation);
|
||||||
|
|
||||||
if (information == null || !information.Exists)
|
return information?.Exists == true;
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return information.SearchPaths.Select(s => Path.Combine(s, "{name}.dll"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFrameworkRedistListPath(NuGetFramework targetFramework)
|
public string GetFrameworkRedistListPath(NuGetFramework targetFramework)
|
||||||
|
@ -87,40 +88,15 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
|
|
||||||
return information.RedistListPath;
|
return information.RedistListPath;
|
||||||
}
|
}
|
||||||
|
private FrameworkInformation GetFrameworkInformation(NuGetFramework targetFramework)
|
||||||
public static string GetReferenceAssembliesPath()
|
|
||||||
{
|
{
|
||||||
// References assemblies are in %ProgramFiles(x86)% on
|
string referenceAssembliesPath = ReferenceAssembliesPath;
|
||||||
// 64 bit machines
|
|
||||||
var programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(programFiles))
|
|
||||||
{
|
|
||||||
// On 32 bit machines they are in %ProgramFiles%
|
|
||||||
programFiles = Environment.GetEnvironmentVariable("ProgramFiles");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(programFiles))
|
|
||||||
{
|
|
||||||
// Reference assemblies aren't installed
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(
|
|
||||||
programFiles,
|
|
||||||
"Reference Assemblies", "Microsoft", "Framework");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FrameworkInformation GetFrameworkInformation(NuGetFramework targetFramework)
|
|
||||||
{
|
|
||||||
string referenceAssembliesPath = GetReferenceAssembliesPath();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(referenceAssembliesPath))
|
if (string.IsNullOrEmpty(referenceAssembliesPath))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NuGetFramework[] candidates;
|
NuGetFramework[] candidates;
|
||||||
if (_aliases.TryGetValue(targetFramework, out candidates))
|
if (_aliases.TryGetValue(targetFramework, out candidates))
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,10 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
|
|
||||||
public CompilerOptions CompilerOptions { get; set; }
|
public CompilerOptions CompilerOptions { get; set; }
|
||||||
|
|
||||||
|
public int Line { get; set; }
|
||||||
|
|
||||||
|
public int Column { get; set; }
|
||||||
|
|
||||||
// REVIEW: Wrapping, we might do this differntly
|
// REVIEW: Wrapping, we might do this differntly
|
||||||
public string WrappedProject { get; set; }
|
public string WrappedProject { get; set; }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue