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:
David Fowler 2015-10-28 02:21:00 -07:00
parent 3b9cfb086c
commit 80beccdbdc
6 changed files with 99 additions and 41 deletions

View 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);
}
}

View file

@ -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);

View file

@ -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)

View file

@ -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>();

View file

@ -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))
{

View file

@ -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; }