dotnet-installer/src/Microsoft.DotNet.Compiler.Common/Executable.cs

137 lines
4.5 KiB
C#
Raw Normal View History

// 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;
2016-02-09 12:01:52 -08:00
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.DotNet.Cli.Compiler.Common;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Files;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Compilation;
using Microsoft.DotNet.ProjectModel.Graph;
using NuGet.Frameworks;
namespace Microsoft.Dotnet.Cli.Compiler.Common
{
public class Executable
{
private readonly ProjectContext _context;
2016-02-03 10:57:25 -08:00
private readonly OutputPaths _outputPaths;
2016-02-03 10:57:25 -08:00
private readonly LibraryExporter _exporter;
public Executable(ProjectContext context, OutputPaths outputPaths, LibraryExporter exporter)
{
_context = context;
2016-02-03 10:57:25 -08:00
_outputPaths = outputPaths;
_exporter = exporter;
}
2016-02-03 10:57:25 -08:00
public void MakeCompilationOutputRunnable()
{
2016-02-09 10:51:03 -08:00
if (string.IsNullOrEmpty(_context.RuntimeIdentifier))
{
throw new InvalidOperationException($"Can not make output runnable for framework {_context.TargetFramework}, because it doesn't have runtime target");
}
2016-02-03 10:57:25 -08:00
var outputPath = _outputPaths.RuntimeOutputPath;
CopyContentFiles(outputPath);
2016-02-03 10:57:25 -08:00
ExportRuntimeAssets(outputPath);
}
2016-02-03 10:57:25 -08:00
private void ExportRuntimeAssets(string outputPath)
{
if (_context.TargetFramework.IsDesktop())
{
2016-02-03 10:57:25 -08:00
MakeCompilationOutputRunnableForFullFramework(outputPath);
}
else
{
2016-02-03 10:57:25 -08:00
MakeCompilationOutputRunnableForCoreCLR(outputPath);
}
2016-02-03 10:57:25 -08:00
}
private void MakeCompilationOutputRunnableForFullFramework(
2016-02-03 10:57:25 -08:00
string outputPath)
{
2016-02-10 10:07:22 -08:00
CopyAllDependencies(outputPath, _exporter.GetAllExports());
2016-02-03 10:57:25 -08:00
GenerateBindingRedirects(_exporter);
}
2016-02-03 10:57:25 -08:00
private void MakeCompilationOutputRunnableForCoreCLR(string outputPath)
{
2016-02-03 10:57:25 -08:00
WriteDepsFileAndCopyProjectDependencies(_exporter, _context.ProjectFile.Name, outputPath);
// TODO: Pick a host based on the RID
CoreHost.CopyTo(outputPath, _context.ProjectFile.Name + Constants.ExeSuffix);
}
private void CopyContentFiles(string outputPath)
{
var contentFiles = new ContentFiles(_context);
contentFiles.StructuredCopyTo(outputPath);
}
2016-02-10 10:07:22 -08:00
private static void CopyAllDependencies(string outputPath, IEnumerable<LibraryExport> libraryExports)
{
2016-02-10 10:07:22 -08:00
foreach (var libraryExport in libraryExports)
{
libraryExport.RuntimeAssemblies.CopyTo(outputPath);
libraryExport.NativeLibraries.CopyTo(outputPath);
libraryExport.RuntimeAssets.StructuredCopyTo(outputPath);
}
}
private static void WriteDepsFileAndCopyProjectDependencies(
LibraryExporter exporter,
string projectFileName,
string outputPath)
{
exporter
.GetDependencies(LibraryType.Package)
.WriteDepsTo(Path.Combine(outputPath, projectFileName + FileNameSuffixes.Deps));
2016-02-09 12:01:52 -08:00
var projectExports = exporter.GetAllExports()
2016-02-03 10:57:25 -08:00
.Where(e => e.Library.Identity.Type == LibraryType.Project)
2016-02-09 12:01:52 -08:00
.ToArray();
2016-02-10 10:07:22 -08:00
CopyAllDependencies(outputPath, projectExports);
2016-02-03 10:57:25 -08:00
}
2016-02-03 10:57:25 -08:00
public void GenerateBindingRedirects(LibraryExporter exporter)
{
2016-02-03 10:57:25 -08:00
var outputName = _outputPaths.RuntimeFiles.Assembly;
var existingConfig = new DirectoryInfo(_context.ProjectDirectory)
.EnumerateFiles()
.FirstOrDefault(f => f.Name.Equals("app.config", StringComparison.OrdinalIgnoreCase));
XDocument baseAppConfig = null;
if (existingConfig != null)
{
using (var fileStream = File.OpenRead(existingConfig.FullName))
{
baseAppConfig = XDocument.Load(fileStream);
}
}
var appConfig = exporter.GetAllExports().GenerateBindingRedirects(baseAppConfig);
if (appConfig == null) { return; }
var path = outputName + ".config";
using (var stream = File.Create(path))
{
appConfig.Save(stream);
}
}
}
}