dotnet-installer/src/Microsoft.DotNet.Compiler.Common/Executable.cs
Andrew Stanton-Nurse 7cc90d9ad1 Update dotnet-build to produce portable layout
dotnet-build will produce a deps file for portable builds, and will now
create "runnable" outputs for RID-less targets

the outputs won't actually be runnable today because we need corehost
changes and to generate a deps.json file for corehost to use.
2016-03-08 11:46:15 -08:00

145 lines
4.7 KiB
C#

// 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;
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;
private readonly LibraryExporter _exporter;
private readonly OutputPaths _outputPaths;
private readonly string _runtimeOutputPath;
private readonly string _intermediateOutputPath;
public Executable(ProjectContext context, OutputPaths outputPaths, LibraryExporter exporter)
{
_context = context;
_outputPaths = outputPaths;
_runtimeOutputPath = outputPaths.RuntimeOutputPath;
_intermediateOutputPath = outputPaths.IntermediateOutputDirectoryPath;
_exporter = exporter;
}
public void MakeCompilationOutputRunnable()
{
CopyContentFiles();
ExportRuntimeAssets();
}
private void ExportRuntimeAssets()
{
if (_context.TargetFramework.IsDesktop())
{
MakeCompilationOutputRunnableForFullFramework();
}
else
{
MakeCompilationOutputRunnableForCoreCLR();
}
}
private void MakeCompilationOutputRunnableForFullFramework()
{
var dependencies = _exporter.GetDependencies();
CopyAssemblies(dependencies);
CopyAssets(dependencies);
GenerateBindingRedirects(_exporter);
}
private void MakeCompilationOutputRunnableForCoreCLR()
{
WriteDepsFileAndCopyProjectDependencies(_exporter);
if (!string.IsNullOrEmpty(_context.RuntimeIdentifier))
{
// TODO: Pick a host based on the RID
CoreHost.CopyTo(_runtimeOutputPath, _context.ProjectFile.Name + Constants.ExeSuffix);
}
}
private void CopyContentFiles()
{
var contentFiles = new ContentFiles(_context);
contentFiles.StructuredCopyTo(_runtimeOutputPath);
}
private void CopyAssemblies(IEnumerable<LibraryExport> libraryExports)
{
foreach (var libraryExport in libraryExports)
{
libraryExport.RuntimeAssemblies.CopyTo(_runtimeOutputPath);
libraryExport.NativeLibraries.CopyTo(_runtimeOutputPath);
}
}
private void CopyAssets(IEnumerable<LibraryExport> libraryExports)
{
foreach (var libraryExport in libraryExports)
{
libraryExport.RuntimeAssets.StructuredCopyTo(
_runtimeOutputPath,
_intermediateOutputPath);
}
}
private void WriteDepsFileAndCopyProjectDependencies(LibraryExporter exporter)
{
exporter
.GetDependencies(LibraryType.Package)
.WriteDepsTo(Path.Combine(_runtimeOutputPath, _context.ProjectFile.Name + FileNameSuffixes.Deps));
var projectExports = exporter.GetDependencies(LibraryType.Project);
CopyAssemblies(projectExports);
CopyAssets(projectExports);
var packageExports = exporter.GetDependencies(LibraryType.Package);
CopyAssets(packageExports);
}
public void GenerateBindingRedirects(LibraryExporter exporter)
{
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);
}
}
}
}