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
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
|
||||
{
|
||||
public static class ErrorCodes
|
||||
public static partial class ErrorCodes
|
||||
{
|
||||
// The dependency A could not be resolved.
|
||||
public static readonly string NU1001 = nameof(NU1001);
|
|
@ -1,7 +1,8 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.ProjectModel.Graph;
|
||||
using Microsoft.Extensions.ProjectModel.Resolution;
|
||||
|
@ -26,6 +27,8 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
public string ProjectDirectory { get; set; }
|
||||
|
||||
public string PackagesDirectory { get; set; }
|
||||
|
||||
public string ReferenceAssembliesPath { get; set; }
|
||||
|
||||
public ProjectContext Build()
|
||||
{
|
||||
|
@ -44,6 +47,7 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
|
||||
RootDirectory = GlobalSettings?.DirectoryPath ?? RootDirectory;
|
||||
PackagesDirectory = PackagesDirectory ?? PackageDependencyProvider.ResolveRepositoryPath(RootDirectory, GlobalSettings);
|
||||
ReferenceAssembliesPath = ReferenceAssembliesPath ?? GetDefaultReferenceAssembliesPath();
|
||||
|
||||
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);
|
||||
bool requiresFrameworkAssemblies;
|
||||
|
||||
// Resolve the dependencies
|
||||
ResolveDependencies(libraries, referenceAssemblyDependencyResolver);
|
||||
ResolveDependencies(libraries, referenceAssemblyDependencyResolver, out requiresFrameworkAssemblies);
|
||||
|
||||
var diagnostics = new List<DiagnosticMessage>();
|
||||
|
||||
|
@ -112,6 +117,22 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
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
|
||||
var libraryManager = new LibraryManager(libraries.Values.ToList(), diagnostics);
|
||||
|
||||
|
@ -124,8 +145,12 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
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())
|
||||
{
|
||||
if (Equals(library.Identity.Type, LibraryType.Package) &&
|
||||
|
@ -146,6 +171,8 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
{
|
||||
if (Equals(LibraryType.ReferenceAssembly, dependency.Target))
|
||||
{
|
||||
requiresFrameworkAssemblies = true;
|
||||
|
||||
dep = referenceAssemblyDependencyResolver.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()
|
||||
{
|
||||
if (Project == null)
|
||||
|
|
|
@ -465,7 +465,9 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
{
|
||||
FrameworkName = frameworkName,
|
||||
Dependencies = new List<LibraryRange>(),
|
||||
CompilerOptions = compilerOptions
|
||||
CompilerOptions = compilerOptions,
|
||||
Line = frameworkValue.Line,
|
||||
Column = frameworkValue.Column
|
||||
};
|
||||
|
||||
var frameworkDependencies = new List<LibraryRange>();
|
||||
|
|
|
@ -14,8 +14,6 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
|||
{
|
||||
public class FrameworkReferenceResolver
|
||||
{
|
||||
// TODO(anurse): Move the Mono stuff back in.
|
||||
|
||||
// FrameworkConstants doesn't have dnx46 yet
|
||||
private static readonly NuGetFramework Dnx46 = new NuGetFramework(
|
||||
FrameworkConstants.FrameworkIdentifiers.Dnx,
|
||||
|
@ -28,6 +26,13 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
|||
{ FrameworkConstants.CommonFrameworks.Dnx451, new [] { FrameworkConstants.CommonFrameworks.Net451 } },
|
||||
{ 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)
|
||||
{
|
||||
|
@ -65,15 +70,11 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
|||
return !string.IsNullOrEmpty(path);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAttemptedPaths(NuGetFramework targetFramework)
|
||||
public bool IsInstalled(NuGetFramework targetFramework)
|
||||
{
|
||||
var information = _cache.GetOrAdd(targetFramework, GetFrameworkInformation);
|
||||
|
||||
if (information == null || !information.Exists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return information.SearchPaths.Select(s => Path.Combine(s, "{name}.dll"));
|
||||
return information?.Exists == true;
|
||||
}
|
||||
|
||||
public string GetFrameworkRedistListPath(NuGetFramework targetFramework)
|
||||
|
@ -87,40 +88,15 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
|||
|
||||
return information.RedistListPath;
|
||||
}
|
||||
|
||||
public static string GetReferenceAssembliesPath()
|
||||
private FrameworkInformation GetFrameworkInformation(NuGetFramework targetFramework)
|
||||
{
|
||||
// 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 static FrameworkInformation GetFrameworkInformation(NuGetFramework targetFramework)
|
||||
{
|
||||
string referenceAssembliesPath = GetReferenceAssembliesPath();
|
||||
string referenceAssembliesPath = ReferenceAssembliesPath;
|
||||
|
||||
if (string.IsNullOrEmpty(referenceAssembliesPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
NuGetFramework[] candidates;
|
||||
if (_aliases.TryGetValue(targetFramework, out candidates))
|
||||
{
|
||||
|
|
|
@ -15,6 +15,10 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
|
||||
public CompilerOptions CompilerOptions { get; set; }
|
||||
|
||||
public int Line { get; set; }
|
||||
|
||||
public int Column { get; set; }
|
||||
|
||||
// REVIEW: Wrapping, we might do this differntly
|
||||
public string WrappedProject { get; set; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue