Merge pull request #1067 from dotnet/davidfowl/output-paths
Fix output paths (and some other stuff associated with it)
This commit is contained in:
commit
4ebc704e67
28 changed files with 343 additions and 277 deletions
|
@ -9,7 +9,6 @@ $TestPackagesPath = "$RepoRoot\tests\packages"
|
|||
|
||||
$ArgTestRoot = "$RepoRoot\test\ArgumentForwardingTests"
|
||||
$ArgTestOutputRoot = "$RepoRoot\artifacts\tests\arg-forwarding"
|
||||
$ArgTestBin = "$ArgTestOutputRoot\$Configuration\dnxcore50"
|
||||
|
||||
dotnet publish --framework "dnxcore50" --runtime "$Rid" --output "$ArgTestOutputRoot" --configuration "$Configuration" "$ArgTestRoot\Reflector"
|
||||
if (!$?) {
|
||||
|
@ -23,9 +22,9 @@ if (!$?) {
|
|||
Exit 1
|
||||
}
|
||||
|
||||
cp "$ArgTestRoot\Reflector\reflector_cmd.cmd" "$ArgTestBin"
|
||||
cp "$ArgTestRoot\Reflector\reflector_cmd.cmd" "$ArgTestOutputRoot"
|
||||
|
||||
pushd "$ArgTestBin"
|
||||
pushd "$ArgTestOutputRoot"
|
||||
|
||||
& ".\corerun" "xunit.console.netcore.exe" "ArgumentForwardingTests.dll" -xml "$_-testResults.xml" -notrait category=failing
|
||||
$exitCode = $LastExitCode
|
||||
|
|
|
@ -19,13 +19,12 @@ source "$DIR/../common/_common.sh"
|
|||
|
||||
ArgTestRoot="$REPOROOT/test/ArgumentForwardingTests"
|
||||
ArgTestOutputRoot="$REPOROOT/artifacts/tests/arg-forwarding"
|
||||
ArgTestBin="$ArgTestOutputRoot/$CONFIGURATION/dnxcore50"
|
||||
|
||||
dotnet publish --framework "dnxcore50" --output "$ArgTestOutputRoot" --configuration "$CONFIGURATION" "$ArgTestRoot/Reflector"
|
||||
dotnet publish --framework "dnxcore50" --output "$ArgTestOutputRoot" --configuration "$CONFIGURATION" "$ArgTestRoot/ArgumentForwardingTests"
|
||||
|
||||
|
||||
|
||||
pushd "$ArgTestBin"
|
||||
pushd "$ArgTestOutputRoot"
|
||||
./corerun "xunit.console.netcore.exe" "ArgumentForwardingTests.dll" -xml "ArgumentForwardingTests-testResults.xml" -notrait category=failing
|
||||
popd
|
||||
|
|
|
@ -24,16 +24,16 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
private static CommandSpec ResolveFromPath(string commandName, IEnumerable<string> args, bool useComSpec = false)
|
||||
{
|
||||
var commandPath = Env.GetCommandPath(commandName);
|
||||
return commandPath == null
|
||||
? null
|
||||
return commandPath == null
|
||||
? null
|
||||
: CreateCommandSpecPreferringExe(commandName, args, commandPath, CommandResolutionStrategy.Path, useComSpec);
|
||||
}
|
||||
|
||||
private static CommandSpec ResolveFromAppBase(string commandName, IEnumerable<string> args, bool useComSpec = false)
|
||||
{
|
||||
var commandPath = Env.GetCommandPathFromAppBase(AppContext.BaseDirectory, commandName);
|
||||
return commandPath == null
|
||||
? null
|
||||
return commandPath == null
|
||||
? null
|
||||
: CreateCommandSpecPreferringExe(commandName, args, commandPath, CommandResolutionStrategy.BaseDirectory, useComSpec);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args);
|
||||
return new CommandSpec(commandName, escapedArgs, CommandResolutionStrategy.Path);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -69,7 +69,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
|
||||
if (commandPackage == null) return null;
|
||||
|
||||
var depsPath = GetDepsPath(projectContext, Constants.DefaultConfiguration);
|
||||
var depsPath = projectContext.GetOutputPathCalculator().GetDepsPath(Constants.DefaultConfiguration);
|
||||
|
||||
return ConfigureCommandFromPackage(commandName, args, commandPackage, projectContext, depsPath, useComSpec);
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
private static PackageDescription GetCommandPackage(ProjectContext projectContext, string commandName)
|
||||
{
|
||||
return projectContext.LibraryManager.GetLibraries()
|
||||
.Where(l => l.GetType() == typeof (PackageDescription))
|
||||
.Where(l => l.GetType() == typeof(PackageDescription))
|
||||
.Select(l => l as PackageDescription)
|
||||
.FirstOrDefault(p => p.Library.Files
|
||||
.Select(Path.GetFileName)
|
||||
|
@ -201,21 +201,13 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args);
|
||||
return new CommandSpec(fileName, escapedArgs, CommandResolutionStrategy.NugetPackage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static string GetDepsPath(ProjectContext context, string buildConfiguration)
|
||||
{
|
||||
return Path.Combine(context.GetOutputDirectoryPath(buildConfiguration),
|
||||
context.ProjectFile.Name + FileNameSuffixes.Deps);
|
||||
}
|
||||
|
||||
private static CommandSpec CreateCommandSpecPreferringExe(
|
||||
string commandName,
|
||||
IEnumerable<string> args,
|
||||
string commandName,
|
||||
IEnumerable<string> args,
|
||||
string commandPath,
|
||||
CommandResolutionStrategy resolutionStrategy,
|
||||
CommandResolutionStrategy resolutionStrategy,
|
||||
bool useComSpec = false)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
|
||||
|
@ -226,7 +218,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
// Use cmd if we can't find an exe
|
||||
if (preferredCommandPath == null)
|
||||
{
|
||||
useComSpec = true;
|
||||
useComSpec = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -246,8 +238,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
}
|
||||
|
||||
private static CommandSpec CreateComSpecCommandSpec(
|
||||
string command,
|
||||
IEnumerable<string> args,
|
||||
string command,
|
||||
IEnumerable<string> args,
|
||||
CommandResolutionStrategy resolutionStrategy)
|
||||
{
|
||||
// To prevent Command Not Found, comspec gets passed in as
|
||||
|
|
|
@ -20,8 +20,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
}
|
||||
|
||||
public static Reporter Output { get; } = Create(AnsiConsole.GetOutput);
|
||||
public static Reporter Error { get; } = Create(AnsiConsole.GetError);
|
||||
public static Reporter Verbose { get; } = CommandContext.IsVerbose() ? Create(AnsiConsole.GetError) : Null;
|
||||
public static Reporter Error { get; } = Create(AnsiConsole.GetOutput);
|
||||
public static Reporter Verbose { get; } = CommandContext.IsVerbose() ? Create(AnsiConsole.GetOutput) : Null;
|
||||
|
||||
public static Reporter Create(Func<bool, AnsiConsole> getter)
|
||||
{
|
||||
|
|
|
@ -1,22 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||
{
|
||||
public static class LibraryExporterExtensions
|
||||
{
|
||||
internal static void CopyProjectDependenciesTo(this LibraryExporter exporter, string path, params ProjectDescription[] except)
|
||||
{
|
||||
exporter.GetAllExports()
|
||||
.Where(e => !except.Contains(e.Library))
|
||||
.Where(e => e.Library is ProjectDescription)
|
||||
.SelectMany(e => e.NativeLibraries.Union(e.RuntimeAssemblies))
|
||||
.CopyTo(path);
|
||||
}
|
||||
|
||||
public static void WriteDepsTo(this IEnumerable<LibraryExport> exports, string path)
|
||||
{
|
||||
File.WriteAllLines(path, exports.SelectMany(GenerateLines));
|
||||
|
@ -42,16 +32,18 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
|||
}));
|
||||
}
|
||||
|
||||
internal static IEnumerable<LibraryAsset> RuntimeAssets(this LibraryExport export)
|
||||
internal static IEnumerable<string> RuntimeAssets(this LibraryExport export)
|
||||
{
|
||||
return export.RuntimeAssemblies.Union(export.NativeLibraries);
|
||||
return export.RuntimeAssemblies.Union(export.NativeLibraries)
|
||||
.Select(e => e.ResolvedPath)
|
||||
.Union(export.RuntimeAssets);
|
||||
}
|
||||
|
||||
internal static void CopyTo(this IEnumerable<LibraryAsset> assets, string destinationPath)
|
||||
internal static void CopyTo(this IEnumerable<string> assets, string destinationPath)
|
||||
{
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
File.Copy(asset.ResolvedPath, Path.Combine(destinationPath, Path.GetFileName(asset.ResolvedPath)),
|
||||
File.Copy(asset, Path.Combine(destinationPath, Path.GetFileName(asset)),
|
||||
overwrite: true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
|||
public static class ProjectContextExtensions
|
||||
{
|
||||
public static string ProjectName(this ProjectContext context) => context.RootProject.Identity.Name;
|
||||
public static string GetDisplayName(this ProjectContext context) => $"{context.RootProject.Identity.Name} ({context.TargetFramework})";
|
||||
|
||||
public static void MakeCompilationOutputRunnable(this ProjectContext context, string outputPath, string configuration)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Microsoft.DotNet.ProjectModel.Loader
|
|||
dllImports,
|
||||
|
||||
// Add the project's output directory path to ensure project-to-project references get located
|
||||
new[] { context.GetOutputDirectoryPath(configuration) });
|
||||
new[] { context.GetOutputPathCalculator().GetOutputDirectoryPath(configuration) });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
/// </summary>
|
||||
public IEnumerable<LibraryAsset> RuntimeAssemblies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Non assembly runtime assets.
|
||||
/// </summary>
|
||||
public IEnumerable<string> RuntimeAssets { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of fully-qualified paths to native binaries required to run
|
||||
/// </summary>
|
||||
|
@ -33,26 +38,28 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
/// Gets a list of fully-qualified paths to source code file references
|
||||
/// </summary>
|
||||
public IEnumerable<string> SourceReferences { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of analyzers provided by this export.
|
||||
/// </summary>
|
||||
public IEnumerable<AnalyzerReference> AnalyzerReferences { get; }
|
||||
|
||||
public LibraryExport(LibraryDescription library,
|
||||
IEnumerable<LibraryAsset> compileAssemblies,
|
||||
IEnumerable<string> sourceReferences,
|
||||
IEnumerable<LibraryAsset> runtimeAssemblies,
|
||||
IEnumerable<LibraryAsset> nativeLibraries,
|
||||
IEnumerable<AnalyzerReference> analyzers)
|
||||
{
|
||||
Library = library;
|
||||
CompilationAssemblies = compileAssemblies;
|
||||
SourceReferences = sourceReferences;
|
||||
RuntimeAssemblies = runtimeAssemblies;
|
||||
NativeLibraries = nativeLibraries;
|
||||
AnalyzerReferences = analyzers;
|
||||
}
|
||||
/// <summary>
|
||||
/// Get a list of analyzers provided by this export.
|
||||
/// </summary>
|
||||
public IEnumerable<AnalyzerReference> AnalyzerReferences { get; }
|
||||
|
||||
public LibraryExport(LibraryDescription library,
|
||||
IEnumerable<LibraryAsset> compileAssemblies,
|
||||
IEnumerable<string> sourceReferences,
|
||||
IEnumerable<LibraryAsset> runtimeAssemblies,
|
||||
IEnumerable<string> runtimeAssets,
|
||||
IEnumerable<LibraryAsset> nativeLibraries,
|
||||
IEnumerable<AnalyzerReference> analyzers)
|
||||
{
|
||||
Library = library;
|
||||
CompilationAssemblies = compileAssemblies;
|
||||
SourceReferences = sourceReferences;
|
||||
RuntimeAssemblies = runtimeAssemblies;
|
||||
RuntimeAssets = runtimeAssets;
|
||||
NativeLibraries = nativeLibraries;
|
||||
AnalyzerReferences = analyzers;
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => Library.Identity.ToString();
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
var sourceReferences = new List<string>();
|
||||
var analyzerReferences = new List<AnalyzerReference>();
|
||||
var libraryExport = GetExport(library);
|
||||
|
||||
|
||||
|
||||
// We need to filter out source references from non-root libraries,
|
||||
// so we rebuild the library export
|
||||
|
@ -100,8 +100,13 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
analyzerReferences.AddRange(libraryExport.AnalyzerReferences);
|
||||
}
|
||||
|
||||
yield return new LibraryExport(library, compilationAssemblies, sourceReferences,
|
||||
libraryExport.RuntimeAssemblies, libraryExport.NativeLibraries, analyzerReferences);
|
||||
yield return new LibraryExport(library,
|
||||
compilationAssemblies,
|
||||
sourceReferences,
|
||||
libraryExport.RuntimeAssemblies,
|
||||
libraryExport.RuntimeAssets,
|
||||
libraryExport.NativeLibraries,
|
||||
analyzerReferences);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,26 +147,48 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
{
|
||||
sourceReferences.Add(sharedSource);
|
||||
}
|
||||
|
||||
|
||||
var analyzers = GetAnalyzerReferences(package);
|
||||
|
||||
return new LibraryExport(package, compileAssemblies,
|
||||
sourceReferences, runtimeAssemblies, nativeLibraries, analyzers);
|
||||
sourceReferences, runtimeAssemblies, Array.Empty<string>(), nativeLibraries, analyzers);
|
||||
}
|
||||
|
||||
private LibraryExport ExportProject(ProjectDescription project)
|
||||
{
|
||||
var compileAssemblies = new List<LibraryAsset>();
|
||||
var runtimeAssets = new List<string>();
|
||||
var sourceReferences = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath))
|
||||
{
|
||||
// Project specifies a pre-compiled binary. We're done!
|
||||
var assemblyPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.AssemblyPath);
|
||||
compileAssemblies.Add(new LibraryAsset(
|
||||
var pdbPath = Path.ChangeExtension(assemblyPath, "pdb");
|
||||
|
||||
var compileAsset = new LibraryAsset(
|
||||
project.Project.Name,
|
||||
assemblyPath,
|
||||
Path.Combine(project.Project.ProjectDirectory, assemblyPath)));
|
||||
null,
|
||||
Path.GetFullPath(Path.Combine(project.Project.ProjectDirectory, assemblyPath)));
|
||||
|
||||
compileAssemblies.Add(compileAsset);
|
||||
runtimeAssets.Add(pdbPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputCalculator = project.GetOutputPathCalculator();
|
||||
var assemblyPath = outputCalculator.GetAssemblyPath(_configuration);
|
||||
compileAssemblies.Add(new LibraryAsset(project.Identity.Name, null, assemblyPath));
|
||||
|
||||
foreach (var path in outputCalculator.GetBuildOutputs(_configuration))
|
||||
{
|
||||
if (string.Equals(assemblyPath, path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
runtimeAssets.Add(path);
|
||||
}
|
||||
}
|
||||
|
||||
// Add shared sources
|
||||
|
@ -174,7 +201,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
// just the same as compileAssemblies and nativeLibraries are empty
|
||||
// Also no support for analyzer projects
|
||||
return new LibraryExport(project, compileAssemblies, sourceReferences,
|
||||
compileAssemblies, Array.Empty<LibraryAsset>(), Array.Empty<AnalyzerReference>());
|
||||
compileAssemblies, runtimeAssets, Array.Empty<LibraryAsset>(), Array.Empty<AnalyzerReference>());
|
||||
}
|
||||
|
||||
private static string ResolvePath(Project project, string configuration, string path)
|
||||
|
@ -202,6 +229,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
new[] { new LibraryAsset(library.Identity.Name, library.Path, library.Path) },
|
||||
Array.Empty<string>(),
|
||||
Array.Empty<LibraryAsset>(),
|
||||
Array.Empty<string>(),
|
||||
Array.Empty<LibraryAsset>(),
|
||||
Array.Empty<AnalyzerReference>());
|
||||
}
|
||||
|
@ -214,7 +242,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
.Where(path => path.StartsWith("shared" + Path.DirectorySeparatorChar))
|
||||
.Select(path => Path.Combine(package.Path, path));
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<AnalyzerReference> GetAnalyzerReferences(PackageDescription package)
|
||||
{
|
||||
var analyzers = package
|
||||
|
@ -222,16 +250,16 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
.Files
|
||||
.Where(path => path.StartsWith("analyzers" + Path.DirectorySeparatorChar) &&
|
||||
path.EndsWith(".dll"));
|
||||
|
||||
|
||||
var analyzerRefs = new List<AnalyzerReference>();
|
||||
// See https://docs.nuget.org/create/analyzers-conventions for the analyzer
|
||||
// NuGet specification
|
||||
foreach (var analyzer in analyzers)
|
||||
{
|
||||
var specifiers = analyzer.Split(Path.DirectorySeparatorChar);
|
||||
|
||||
|
||||
var assemblyPath = Path.Combine(package.Path, analyzer);
|
||||
|
||||
|
||||
// $/analyzers/{Framework Name}{Version}/{Supported Architecture}/{Supported Programming Language}/{Analyzer}.dll
|
||||
switch (specifiers.Length)
|
||||
{
|
||||
|
@ -244,7 +272,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
runtimeIdentifier: null
|
||||
));
|
||||
break;
|
||||
|
||||
|
||||
// $/analyzers/{framework}/{analyzer}.dll
|
||||
case 3:
|
||||
analyzerRefs.Add(new AnalyzerReference(
|
||||
|
@ -254,7 +282,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
runtimeIdentifier: null
|
||||
));
|
||||
break;
|
||||
|
||||
|
||||
// $/analyzers/{framework}/{language}/{analyzer}.dll
|
||||
case 4:
|
||||
analyzerRefs.Add(new AnalyzerReference(
|
||||
|
@ -264,7 +292,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
runtimeIdentifier: null
|
||||
));
|
||||
break;
|
||||
|
||||
|
||||
// $/analyzers/{framework}/{runtime}/{language}/{analyzer}.dll
|
||||
case 5:
|
||||
analyzerRefs.Add(new AnalyzerReference(
|
||||
|
@ -274,10 +302,10 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
runtimeIdentifier: specifiers[2]
|
||||
));
|
||||
break;
|
||||
|
||||
// Anything less than 2 specifiers or more than 4 is
|
||||
// illegal according to the specification and will be
|
||||
// ignored
|
||||
|
||||
// Anything less than 2 specifiers or more than 4 is
|
||||
// illegal according to the specification and will be
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
return analyzerRefs;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// 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.Runtime.InteropServices;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectModel
|
||||
|
@ -10,7 +13,10 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
{
|
||||
private const string ObjDirectoryName = "obj";
|
||||
|
||||
private readonly ProjectContext _project;
|
||||
private readonly Project _project;
|
||||
private readonly NuGetFramework _framework;
|
||||
|
||||
private readonly string _runtimeIdentifier;
|
||||
|
||||
/// <summary>
|
||||
/// Unaltered output path. Either what is passed in in the constructor, or the project directory.
|
||||
|
@ -20,10 +26,14 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
public string BaseCompilationOutputPath { get; }
|
||||
|
||||
public OutputPathCalculator(
|
||||
ProjectContext project,
|
||||
Project project,
|
||||
NuGetFramework framework,
|
||||
string runtimeIdentifier,
|
||||
string baseOutputPath)
|
||||
{
|
||||
_project = project;
|
||||
_framework = framework;
|
||||
_runtimeIdentifier = runtimeIdentifier;
|
||||
|
||||
BaseOutputPath = string.IsNullOrWhiteSpace(baseOutputPath) ? _project.ProjectDirectory : baseOutputPath;
|
||||
|
||||
|
@ -32,17 +42,21 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
: baseOutputPath;
|
||||
}
|
||||
|
||||
public string GetCompilationOutputPath(string buildConfiguration)
|
||||
public string GetOutputDirectoryPath(string buildConfiguration)
|
||||
{
|
||||
var outDir = Path.Combine(
|
||||
BaseCompilationOutputPath,
|
||||
var outDir = Path.Combine(BaseCompilationOutputPath,
|
||||
buildConfiguration,
|
||||
_project.TargetFramework.GetTwoDigitShortFolderName());
|
||||
_framework.GetShortFolderName());
|
||||
|
||||
if (!string.IsNullOrEmpty(_runtimeIdentifier))
|
||||
{
|
||||
outDir = Path.Combine(outDir, _runtimeIdentifier);
|
||||
}
|
||||
|
||||
return outDir;
|
||||
}
|
||||
|
||||
public string GetIntermediateOutputPath(string buildConfiguration, string intermediateOutputValue)
|
||||
public string GetIntermediateOutputDirectoryPath(string buildConfiguration, string intermediateOutputValue)
|
||||
{
|
||||
string intermediateOutputPath;
|
||||
|
||||
|
@ -52,7 +66,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
BaseOutputPath,
|
||||
ObjDirectoryName,
|
||||
buildConfiguration,
|
||||
_project.TargetFramework.GetTwoDigitShortFolderName());
|
||||
_framework.GetTwoDigitShortFolderName());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -61,5 +75,79 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
return intermediateOutputPath;
|
||||
}
|
||||
|
||||
public string GetAssemblyPath(string buildConfiguration)
|
||||
{
|
||||
var compilationOptions = _project.GetCompilerOptions(_framework, buildConfiguration);
|
||||
var outputExtension = FileNameSuffixes.DotNet.DynamicLib;
|
||||
|
||||
if (_framework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault())
|
||||
{
|
||||
outputExtension = FileNameSuffixes.DotNet.Exe;
|
||||
}
|
||||
|
||||
return Path.Combine(
|
||||
GetOutputDirectoryPath(buildConfiguration),
|
||||
_project.Name + outputExtension);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetBuildOutputs(string buildConfiguration)
|
||||
{
|
||||
var assemblyPath = GetAssemblyPath(buildConfiguration);
|
||||
|
||||
yield return assemblyPath;
|
||||
yield return Path.ChangeExtension(assemblyPath, "pdb");
|
||||
|
||||
var compilationOptions = _project.GetCompilerOptions(_framework, buildConfiguration);
|
||||
|
||||
if (compilationOptions.GenerateXmlDocumentation == true)
|
||||
{
|
||||
yield return Path.ChangeExtension(assemblyPath, "xml");
|
||||
}
|
||||
|
||||
// This should only exist in desktop framework
|
||||
var configFile = assemblyPath + ".config";
|
||||
|
||||
if (File.Exists(configFile))
|
||||
{
|
||||
yield return configFile;
|
||||
}
|
||||
|
||||
// Deps file
|
||||
var depsFile = GetDepsPath(buildConfiguration);
|
||||
|
||||
if (File.Exists(depsFile))
|
||||
{
|
||||
yield return depsFile;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetDepsPath(string buildConfiguration)
|
||||
{
|
||||
return Path.Combine(GetOutputDirectoryPath(buildConfiguration), _project.Name + FileNameSuffixes.Deps);
|
||||
}
|
||||
|
||||
public string GetExecutablePath(string buildConfiguration)
|
||||
{
|
||||
var extension = FileNameSuffixes.CurrentPlatform.Exe;
|
||||
|
||||
// This is the check for mono, if we're not on windows and producing outputs for
|
||||
// the desktop framework then it's an exe
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && _framework.IsDesktop())
|
||||
{
|
||||
extension = FileNameSuffixes.DotNet.Exe;
|
||||
}
|
||||
|
||||
return Path.Combine(
|
||||
GetOutputDirectoryPath(buildConfiguration),
|
||||
_project.Name + extension);
|
||||
}
|
||||
|
||||
public string GetPdbPath(string buildConfiguration)
|
||||
{
|
||||
return Path.Combine(
|
||||
GetOutputDirectoryPath(buildConfiguration),
|
||||
_project.Name + FileNameSuffixes.DotNet.ProgramDatabase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,37 +120,9 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
.BuildAllTargets();
|
||||
}
|
||||
|
||||
public string GetAssemblyPath(string buildConfiguration)
|
||||
public OutputPathCalculator GetOutputPathCalculator(string baseOutputPath = null)
|
||||
{
|
||||
return Path.Combine(
|
||||
GetOutputDirectoryPath(buildConfiguration),
|
||||
ProjectFile.Name + FileNameSuffixes.DotNet.DynamicLib);
|
||||
}
|
||||
|
||||
public string GetPdbPath(string buildConfiguration)
|
||||
{
|
||||
return Path.Combine(
|
||||
GetOutputDirectoryPath(buildConfiguration),
|
||||
ProjectFile.Name + FileNameSuffixes.DotNet.ProgramDatabase);
|
||||
}
|
||||
|
||||
public string GetOutputDirectoryPath(string buildConfiguration)
|
||||
{
|
||||
var outDir = Path.Combine(
|
||||
ProjectDirectory,
|
||||
DirectoryNames.Bin,
|
||||
buildConfiguration,
|
||||
TargetFramework.GetShortFolderName());
|
||||
if (!string.IsNullOrEmpty(RuntimeIdentifier))
|
||||
{
|
||||
outDir = Path.Combine(outDir, RuntimeIdentifier);
|
||||
}
|
||||
return outDir;
|
||||
}
|
||||
|
||||
public OutputPathCalculator GetOutputPathCalculator(string rootOutputPath)
|
||||
{
|
||||
return new OutputPathCalculator(this, rootOutputPath);
|
||||
return new OutputPathCalculator(ProjectFile, TargetFramework, RuntimeIdentifier, baseOutputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,5 +43,10 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
public Project Project { get; }
|
||||
|
||||
public TargetFrameworkInformation TargetFrameworkInfo { get; }
|
||||
|
||||
public OutputPathCalculator GetOutputPathCalculator()
|
||||
{
|
||||
return new OutputPathCalculator(Project, Framework, runtimeIdentifier: null, baseOutputPath: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -510,7 +510,6 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
if (binNode != null)
|
||||
{
|
||||
targetFrameworkInformation.AssemblyPath = binNode.ValueAsString("assembly");
|
||||
targetFrameworkInformation.PdbPath = binNode.ValueAsString("pdb");
|
||||
}
|
||||
|
||||
project._targetFrameworks[frameworkName] = targetFrameworkInformation;
|
||||
|
|
|
@ -23,7 +23,5 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
public string WrappedProject { get; set; }
|
||||
|
||||
public string AssemblyPath { get; set; }
|
||||
|
||||
public string PdbPath { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -20,7 +19,6 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
// Collects icnremental safety checks and transitively compiles a project context
|
||||
internal class CompileContext
|
||||
{
|
||||
|
||||
public static readonly string[] KnownCompilers = { "csc", "vbc", "fsc" };
|
||||
|
||||
private readonly ProjectContext _rootProject;
|
||||
|
@ -36,13 +34,13 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
|
||||
// Cleaner to clone the args and mutate the clone than have separate CompileContext fields for mutated args
|
||||
// and then reasoning which ones to get from args and which ones from fields.
|
||||
_args = (BuilderCommandApp) args.ShallowCopy();
|
||||
_args = (BuilderCommandApp)args.ShallowCopy();
|
||||
|
||||
// Set up Output Paths. They are unique per each CompileContext
|
||||
var outputPathCalculator = _rootProject.GetOutputPathCalculator(_args.OutputValue);
|
||||
_args.OutputValue = outputPathCalculator.BaseCompilationOutputPath;
|
||||
_args.IntermediateValue =
|
||||
outputPathCalculator.GetIntermediateOutputPath(_args.ConfigValue, _args.IntermediateValue);
|
||||
outputPathCalculator.GetIntermediateOutputDirectoryPath(_args.ConfigValue, _args.IntermediateValue);
|
||||
|
||||
// Set up dependencies
|
||||
_dependencies = new ProjectDependenciesFacade(_rootProject, _args.ConfigValue);
|
||||
|
@ -62,7 +60,7 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
{
|
||||
var dependencyProjectContext = ProjectContext.Create(dependency.Path, dependency.Framework);
|
||||
|
||||
if (!NeedsRebuilding(dependencyProjectContext, new ProjectDependenciesFacade(dependencyProjectContext, _args.ConfigValue)))
|
||||
if (!DependencyNeedsRebuilding(dependencyProjectContext, new ProjectDependenciesFacade(dependencyProjectContext, _args.ConfigValue)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -88,14 +86,24 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
return success;
|
||||
}
|
||||
|
||||
private bool DependencyNeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies)
|
||||
{
|
||||
return NeedsRebuilding(project, dependencies, buildOutputPath: null, intermediateOutputPath: null);
|
||||
}
|
||||
|
||||
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies)
|
||||
{
|
||||
var compilerIO = GetCompileIO(project, _args.ConfigValue, _args.OutputValue, _args.IntermediateValue, dependencies);
|
||||
return NeedsRebuilding(project, dependencies, _args.OutputValue, _args.IntermediateValue);
|
||||
}
|
||||
|
||||
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies, string buildOutputPath, string intermediateOutputPath)
|
||||
{
|
||||
var compilerIO = GetCompileIO(project, _args.ConfigValue, buildOutputPath, intermediateOutputPath, dependencies);
|
||||
|
||||
// rebuild if empty inputs / outputs
|
||||
if (!(compilerIO.Outputs.Any() && compilerIO.Inputs.Any()))
|
||||
{
|
||||
Reporter.Output.WriteLine($"\nProject {project.ProjectName()} will be compiled because it either has empty inputs or outputs");
|
||||
Reporter.Output.WriteLine($"Project {project.GetDisplayName()} will be compiled because it either has empty inputs or outputs");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -125,19 +133,25 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
|
||||
if (!newInputs.Any())
|
||||
{
|
||||
Reporter.Output.WriteLine($"\nProject {project.ProjectName()} was previously compiled. Skipping compilation.");
|
||||
Reporter.Output.WriteLine($"Project {project.GetDisplayName()} was previously compiled. Skipping compilation.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Reporter.Output.WriteLine($"\nProject {project.ProjectName()} will be compiled because some of its inputs were newer than its oldest output.");
|
||||
Reporter.Verbose.WriteLine($"Oldest output item was written at {minDate} : {minOutputPath}");
|
||||
Reporter.Verbose.WriteLine($"Inputs newer than the oldest output item:");
|
||||
Reporter.Output.WriteLine($"Project {project.GetDisplayName()} will be compiled because some of its inputs were newer than its oldest output.");
|
||||
Reporter.Verbose.WriteLine();
|
||||
Reporter.Verbose.WriteLine($" Oldest output item:");
|
||||
Reporter.Verbose.WriteLine($" {minDate}: {minOutputPath}");
|
||||
Reporter.Verbose.WriteLine();
|
||||
|
||||
Reporter.Verbose.WriteLine($" Inputs newer than the oldest output item:");
|
||||
|
||||
foreach (var newInput in newInputs)
|
||||
{
|
||||
Reporter.Verbose.WriteLine($"\t{File.GetLastWriteTime(newInput)}\t:\t{newInput}");
|
||||
Reporter.Verbose.WriteLine($" {File.GetLastWriteTime(newInput)}: {newInput}");
|
||||
}
|
||||
|
||||
Reporter.Verbose.WriteLine();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -150,14 +164,14 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
return false;
|
||||
}
|
||||
|
||||
Reporter.Output.WriteLine($"\nProject {project.ProjectName()} will be compiled because expected {itemsType} are missing. ");
|
||||
Reporter.Verbose.WriteLine($"Project {project.GetDisplayName()} will be compiled because expected {itemsType} are missing.");
|
||||
|
||||
foreach (var missing in missingItems)
|
||||
{
|
||||
Reporter.Verbose.WriteLine($"\t {missing}");
|
||||
Reporter.Verbose.WriteLine($" {missing}");
|
||||
}
|
||||
|
||||
Reporter.Output.WriteLine();
|
||||
Reporter.Verbose.WriteLine(); ;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -205,7 +219,7 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
private List<ProjectContext> GetProjectsToCheck()
|
||||
{
|
||||
// include initial root project
|
||||
var contextsToCheck = new List<ProjectContext>(1 + _dependencies.ProjectDependenciesWithSources.Count) {_rootProject};
|
||||
var contextsToCheck = new List<ProjectContext>(1 + _dependencies.ProjectDependenciesWithSources.Count) { _rootProject };
|
||||
|
||||
// convert ProjectDescription to ProjectContext
|
||||
var dependencyContexts = _dependencies.ProjectDependenciesWithSources.Select
|
||||
|
@ -262,12 +276,8 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
args.Add("--framework");
|
||||
args.Add($"{projectDependency.Framework}");
|
||||
args.Add("--configuration");
|
||||
args.Add($"{_args.ConfigValue}");
|
||||
args.Add("--output");
|
||||
args.Add($"{_args.OutputValue}");
|
||||
args.Add("--temp-output");
|
||||
args.Add($"{_args.IntermediateValue}");
|
||||
args.Add($"{projectDependency.Project.ProjectDirectory}");
|
||||
args.Add(_args.ConfigValue);
|
||||
args.Add(projectDependency.Project.ProjectDirectory);
|
||||
|
||||
if (_args.NoHostValue)
|
||||
{
|
||||
|
@ -295,20 +305,20 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
args.Add("--temp-output");
|
||||
args.Add(_args.IntermediateValue);
|
||||
|
||||
if (_args.NoHostValue)
|
||||
{
|
||||
args.Add("--no-host");
|
||||
if (_args.NoHostValue)
|
||||
{
|
||||
args.Add("--no-host");
|
||||
}
|
||||
|
||||
//native args
|
||||
if (_args.IsNativeValue)
|
||||
{
|
||||
args.Add("--native");
|
||||
if (_args.IsNativeValue)
|
||||
{
|
||||
args.Add("--native");
|
||||
}
|
||||
|
||||
if (_args.IsCppModeValue)
|
||||
{
|
||||
args.Add("--cpp");
|
||||
if (_args.IsCppModeValue)
|
||||
{
|
||||
args.Add("--cpp");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_args.ArchValue))
|
||||
|
@ -337,7 +347,7 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
|
||||
args.Add(_rootProject.ProjectDirectory);
|
||||
|
||||
var compileResult = Command.Create("dotnet-compile",args)
|
||||
var compileResult = Command.Create("dotnet-compile", args)
|
||||
.ForwardStdOut()
|
||||
.ForwardStdErr()
|
||||
.Execute();
|
||||
|
@ -387,11 +397,16 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
// computes all the inputs and outputs that would be used in the compilation of a project
|
||||
// ensures that all paths are files
|
||||
// ensures no missing inputs
|
||||
public static CompilerIO GetCompileIO(ProjectContext project, string config, string outputPath, string intermediaryOutputPath, ProjectDependenciesFacade dependencies)
|
||||
public static CompilerIO GetCompileIO(
|
||||
ProjectContext project,
|
||||
string buildConfiguration,
|
||||
string outputPath,
|
||||
string intermediaryOutputPath,
|
||||
ProjectDependenciesFacade dependencies)
|
||||
{
|
||||
var compilerIO = new CompilerIO(new List<string>(), new List<string>());
|
||||
var binariesOutputPath = project.GetOutputPathCalculator(outputPath).GetCompilationOutputPath(config);
|
||||
var compilationOutput = CompilerUtil.GetCompilationOutput(project.ProjectFile, project.TargetFramework, config, binariesOutputPath);
|
||||
var calculator = project.GetOutputPathCalculator(outputPath);
|
||||
var binariesOutputPath = calculator.GetOutputDirectoryPath(buildConfiguration);
|
||||
|
||||
// input: project.json
|
||||
compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath);
|
||||
|
@ -406,11 +421,14 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
// input: dependencies
|
||||
AddDependencies(dependencies, compilerIO);
|
||||
|
||||
// output: compiler output
|
||||
compilerIO.Outputs.Add(compilationOutput);
|
||||
|
||||
// input / output: compilation options files
|
||||
AddFilesFromCompilationOptions(project, config, compilationOutput, compilerIO);
|
||||
// output: compiler outputs
|
||||
foreach (var path in calculator.GetBuildOutputs(buildConfiguration))
|
||||
{
|
||||
compilerIO.Outputs.Add(path);
|
||||
}
|
||||
|
||||
// input compilation options files
|
||||
AddCompilationOptions(project, buildConfiguration, compilerIO);
|
||||
|
||||
// input / output: resources without culture
|
||||
AddCultureResources(project, intermediaryOutputPath, compilerIO);
|
||||
|
@ -423,7 +441,7 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
|
||||
private static void AddLockFile(ProjectContext project, CompilerIO compilerIO)
|
||||
{
|
||||
if(project.LockFile == null)
|
||||
if (project.LockFile == null)
|
||||
{
|
||||
var errorMessage = $"Project {project.ProjectName()} does not have a lock file.";
|
||||
Reporter.Error.WriteLine(errorMessage);
|
||||
|
@ -441,19 +459,10 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
// non project dependencies get captured by changes in the lock file
|
||||
}
|
||||
|
||||
private static void AddFilesFromCompilationOptions(ProjectContext project, string config, string compilationOutput, CompilerIO compilerIO)
|
||||
private static void AddCompilationOptions(ProjectContext project, string config, CompilerIO compilerIO)
|
||||
{
|
||||
var compilerOptions = CompilerUtil.ResolveCompilationOptions(project, config);
|
||||
|
||||
// output: pdb file. They are always emitted (see compiler.csc)
|
||||
compilerIO.Outputs.Add(Path.ChangeExtension(compilationOutput, "pdb"));
|
||||
|
||||
// output: documentation file
|
||||
if (compilerOptions.GenerateXmlDocumentation == true)
|
||||
{
|
||||
compilerIO.Outputs.Add(Path.ChangeExtension(compilationOutput, "xml"));
|
||||
}
|
||||
|
||||
// input: key file
|
||||
if (compilerOptions.KeyFile != null)
|
||||
{
|
||||
|
|
|
@ -125,20 +125,6 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
// used in incremental compilation
|
||||
public static IEnumerable<string> GetCompilationSources(ProjectContext project) => project.ProjectFile.Files.SourceFiles;
|
||||
|
||||
// used in incremental compilation
|
||||
public static string GetCompilationOutput(Project project, NuGetFramework framework, string configuration, string outputPath)
|
||||
{
|
||||
var compilationOptions = project.GetCompilerOptions(framework, configuration);
|
||||
var outputExtension = ".dll";
|
||||
|
||||
if (framework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault())
|
||||
{
|
||||
outputExtension = ".exe";
|
||||
}
|
||||
|
||||
return Path.Combine(outputPath, project.Name + outputExtension);
|
||||
}
|
||||
|
||||
// used in incremental compilation for the key file
|
||||
public static CommonCompilerOptions ResolveCompilationOptions(ProjectContext context, string configuration)
|
||||
{
|
||||
|
|
|
@ -57,22 +57,21 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
}
|
||||
|
||||
private static bool CompileNative(
|
||||
ProjectContext context,
|
||||
ProjectContext context,
|
||||
CompilerCommandApp args)
|
||||
{
|
||||
var outputPathCalculator = context.GetOutputPathCalculator(args.OutputValue);
|
||||
var outputPath = outputPathCalculator.GetCompilationOutputPath(args.ConfigValue);
|
||||
var outputPath = outputPathCalculator.GetOutputDirectoryPath(args.ConfigValue);
|
||||
var nativeOutputPath = Path.Combine(outputPath, "native");
|
||||
var intermediateOutputPath =
|
||||
outputPathCalculator.GetIntermediateOutputPath(args.ConfigValue, args.IntermediateValue);
|
||||
outputPathCalculator.GetIntermediateOutputDirectoryPath(args.ConfigValue, args.IntermediateValue);
|
||||
var nativeIntermediateOutputPath = Path.Combine(intermediateOutputPath, "native");
|
||||
Directory.CreateDirectory(nativeOutputPath);
|
||||
Directory.CreateDirectory(nativeIntermediateOutputPath);
|
||||
|
||||
var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, args.ConfigValue);
|
||||
var managedOutput =
|
||||
CompilerUtil.GetCompilationOutput(context.ProjectFile, context.TargetFramework, args.ConfigValue, outputPath);
|
||||
|
||||
var managedOutput = outputPathCalculator.GetAssemblyPath(args.ConfigValue);
|
||||
|
||||
var nativeArgs = new List<string>();
|
||||
|
||||
// Input Assembly
|
||||
|
@ -83,8 +82,8 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
{
|
||||
nativeArgs.Add("--ilcargs");
|
||||
nativeArgs.Add($"{args.IlcArgsValue}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ILC Path
|
||||
if (!string.IsNullOrWhiteSpace(args.IlcPathValue))
|
||||
{
|
||||
|
@ -107,7 +106,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
}
|
||||
|
||||
// CodeGen Mode
|
||||
if(args.IsCppModeValue)
|
||||
if (args.IsCppModeValue)
|
||||
{
|
||||
nativeArgs.Add("--mode");
|
||||
nativeArgs.Add("cpp");
|
||||
|
@ -139,7 +138,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
// Output Path
|
||||
nativeArgs.Add("--output");
|
||||
nativeArgs.Add($"{nativeOutputPath}");
|
||||
nativeArgs.Add($"{nativeOutputPath}");
|
||||
|
||||
// Write Response File
|
||||
var rsp = Path.Combine(nativeIntermediateOutputPath, $"dotnet-compile-native.{context.ProjectFile.Name}.rsp");
|
||||
|
@ -161,9 +160,9 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
{
|
||||
// Set up Output Paths
|
||||
var outputPathCalculator = context.GetOutputPathCalculator(args.OutputValue);
|
||||
var outputPath = outputPathCalculator.GetCompilationOutputPath(args.ConfigValue);
|
||||
var outputPath = outputPathCalculator.GetOutputDirectoryPath(args.ConfigValue);
|
||||
var intermediateOutputPath =
|
||||
outputPathCalculator.GetIntermediateOutputPath(args.ConfigValue, args.IntermediateValue);
|
||||
outputPathCalculator.GetIntermediateOutputDirectoryPath(args.ConfigValue, args.IntermediateValue);
|
||||
|
||||
Directory.CreateDirectory(outputPath);
|
||||
Directory.CreateDirectory(intermediateOutputPath);
|
||||
|
@ -201,7 +200,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
}
|
||||
|
||||
// Get compilation options
|
||||
var outputName = CompilerUtil.GetCompilationOutput(context.ProjectFile, context.TargetFramework, args.ConfigValue, outputPath);
|
||||
var outputName = outputPathCalculator.GetAssemblyPath(args.ConfigValue);
|
||||
|
||||
// Assemble args
|
||||
var compilerArgs = new List<string>()
|
||||
|
@ -223,21 +222,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
var projectDependency = dependency.Library as ProjectDescription;
|
||||
|
||||
if (projectDependency != null)
|
||||
{
|
||||
if (projectDependency.Project.Files.SourceFiles.Any())
|
||||
{
|
||||
var projectOutputPath = CompilerUtil.GetCompilationOutput(projectDependency.Project, projectDependency.Framework, args.ConfigValue, outputPath);
|
||||
references.Add(projectOutputPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath));
|
||||
}
|
||||
|
||||
references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath));
|
||||
compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\""));
|
||||
|
||||
// Add analyzer references
|
||||
|
@ -289,7 +274,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
var compilerName = CompilerUtil.ResolveCompilerName(context);
|
||||
|
||||
// Write RSP file
|
||||
var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.{context.ProjectFile.Name}.rsp");
|
||||
var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp");
|
||||
File.WriteAllLines(rsp, compilerArgs);
|
||||
|
||||
// Run pre-compile event
|
||||
|
@ -303,7 +288,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
};
|
||||
RunScripts(context, ScriptNames.PreCompile, contextVariables);
|
||||
|
||||
var result = Command.Create($"dotnet-compile-{compilerName}", new [] {"@" + $"{rsp}" })
|
||||
var result = Command.Create($"dotnet-compile-{compilerName}", new[] { "@" + $"{rsp}" })
|
||||
.OnErrorLine(line =>
|
||||
{
|
||||
var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
|
||||
|
@ -359,12 +344,16 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
generateBindingRedirects = true;
|
||||
var projectContext =
|
||||
ProjectContext.Create(context.ProjectDirectory, context.TargetFramework,
|
||||
new[] { PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier()});
|
||||
new[] { PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier() });
|
||||
|
||||
projectContext
|
||||
.CreateExporter(args.ConfigValue)
|
||||
.GetDependencies(LibraryType.Package)
|
||||
.WriteDepsTo(Path.Combine(outputPath, projectContext.ProjectFile.Name + FileNameSuffixes.Deps));
|
||||
// Don't generate a deps file if we're on desktop
|
||||
if (!context.TargetFramework.IsDesktop())
|
||||
{
|
||||
projectContext
|
||||
.CreateExporter(args.ConfigValue)
|
||||
.GetDependencies(LibraryType.Package)
|
||||
.WriteDepsTo(Path.Combine(outputPath, projectContext.ProjectFile.Name + FileNameSuffixes.Deps));
|
||||
}
|
||||
}
|
||||
|
||||
if (generateBindingRedirects && context.TargetFramework.IsDesktop())
|
||||
|
@ -387,12 +376,6 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyExport(string outputPath, LibraryExport export)
|
||||
{
|
||||
CopyFiles(export.RuntimeAssemblies, outputPath);
|
||||
CopyFiles(export.NativeLibraries, outputPath);
|
||||
}
|
||||
|
||||
private static bool PrintSummary(List<DiagnosticMessage> diagnostics, Stopwatch sw, bool success = true)
|
||||
{
|
||||
|
|
|
@ -77,39 +77,39 @@ namespace Microsoft.DotNet.Tools.Publish
|
|||
/// <param name="configuration">Debug or Release</param>
|
||||
/// <param name="nativeSubdirectories"></param>
|
||||
/// <returns>Return 0 if successful else return non-zero</returns>
|
||||
private static bool PublishProjectContext(ProjectContext context, string baseOutputPath, string configuration, bool nativeSubdirectories)
|
||||
private static bool PublishProjectContext(ProjectContext context, string outputPath, string configuration, bool nativeSubdirectories)
|
||||
{
|
||||
Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}/{context.RuntimeIdentifier.Yellow()}");
|
||||
|
||||
var options = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
|
||||
var outputPathCalculator = context.GetOutputPathCalculator(baseOutputPath);
|
||||
var outputPath = outputPathCalculator.GetCompilationOutputPath(configuration);
|
||||
|
||||
if (string.IsNullOrEmpty(outputPath))
|
||||
{
|
||||
outputPath = context.GetOutputPathCalculator().GetOutputDirectoryPath(configuration);
|
||||
}
|
||||
|
||||
var contextVariables = new Dictionary<string, string>
|
||||
{
|
||||
{ "publish:ProjectPath", context.ProjectDirectory },
|
||||
{ "publish:Configuration", configuration },
|
||||
{ "publish:OutputPath", outputPath },
|
||||
{ "publish:PublishOutputPath", outputPathCalculator.BaseCompilationOutputPath },
|
||||
{ "publish:Framework", context.TargetFramework.Framework },
|
||||
{ "publish:Runtime", context.RuntimeIdentifier },
|
||||
};
|
||||
|
||||
RunScripts(context, ScriptNames.PrePublish, contextVariables);
|
||||
|
||||
if (!Directory.Exists(outputPathCalculator.BaseCompilationOutputPath))
|
||||
if (!Directory.Exists(outputPath))
|
||||
{
|
||||
Directory.CreateDirectory(outputPathCalculator.BaseCompilationOutputPath);
|
||||
Directory.CreateDirectory(outputPath);
|
||||
}
|
||||
|
||||
// Compile the project (and transitively, all it's dependencies)
|
||||
var result = Command.Create("dotnet-build",
|
||||
var result = Command.Create("dotnet-build",
|
||||
new string[] {
|
||||
"--framework",
|
||||
"--framework",
|
||||
$"{context.TargetFramework.DotNetFrameworkName}",
|
||||
"--output",
|
||||
$"{outputPathCalculator.BaseCompilationOutputPath}",
|
||||
"--configuration",
|
||||
"--configuration",
|
||||
$"{configuration}",
|
||||
"--no-host",
|
||||
$"{context.ProjectFile.ProjectDirectory}"
|
||||
|
@ -128,16 +128,11 @@ namespace Microsoft.DotNet.Tools.Publish
|
|||
|
||||
foreach (var export in exporter.GetAllExports())
|
||||
{
|
||||
// Skip copying project references
|
||||
if (export.Library is ProjectDescription)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ...");
|
||||
|
||||
PublishFiles(export.RuntimeAssemblies, outputPath, false);
|
||||
PublishFiles(export.RuntimeAssemblies, outputPath, nativeSubdirectories: false);
|
||||
PublishFiles(export.NativeLibraries, outputPath, nativeSubdirectories);
|
||||
PublishFiles(export.RuntimeAssets, outputPath);
|
||||
}
|
||||
|
||||
CopyContents(context, outputPath);
|
||||
|
@ -180,6 +175,14 @@ namespace Microsoft.DotNet.Tools.Publish
|
|||
|
||||
return 0;
|
||||
}
|
||||
private static void PublishFiles(IEnumerable<string> files, string outputPath)
|
||||
{
|
||||
foreach (var file in files)
|
||||
{
|
||||
var targetPath = Path.Combine(outputPath, Path.GetFileName(file));
|
||||
File.Copy(file, targetPath, overwrite: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PublishFiles(IEnumerable<LibraryAsset> files, string outputPath, bool nativeSubdirectories)
|
||||
{
|
||||
|
@ -191,7 +194,7 @@ namespace Microsoft.DotNet.Tools.Publish
|
|||
{
|
||||
Directory.CreateDirectory(destinationDirectory);
|
||||
}
|
||||
|
||||
|
||||
File.Copy(file.ResolvedPath, Path.Combine(destinationDirectory, Path.GetFileName(file.ResolvedPath)), overwrite: true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,15 +112,14 @@ namespace Microsoft.DotNet.Tools.Run
|
|||
}
|
||||
|
||||
// Now launch the output and give it the results
|
||||
var outputName = Path.Combine(
|
||||
_context.GetOutputPathCalculator(tempDir).GetCompilationOutputPath(Configuration),
|
||||
_context.ProjectFile.Name + Constants.ExeSuffix);
|
||||
var outputName = _context.GetOutputPathCalculator(tempDir).GetExecutablePath(Configuration);
|
||||
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
if (_context.TargetFramework.IsDesktop())
|
||||
{
|
||||
// Run mono if we're running a desktop target on non windows
|
||||
_args.Insert(0, outputName + ".exe");
|
||||
_args.Insert(0, outputName);
|
||||
|
||||
if (string.Equals(Configuration, "Debug", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
var parentProcessIdOption = app.Option("--parentProcessId", "Used by IDEs to specify their process ID. Test will exit if the parent process does.", CommandOptionType.SingleValue);
|
||||
var portOption = app.Option("--port", "Used by IDEs to specify a port number to listen for a connection.", CommandOptionType.SingleValue);
|
||||
var projectPath = app.Argument("<PROJECT>", "The project to test, defaults to the current directory. Can be a path to a project.json or a project directory.");
|
||||
|
||||
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
try
|
||||
|
@ -51,17 +51,17 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
|
||||
RegisterForParentProcessExit(processId);
|
||||
}
|
||||
|
||||
|
||||
var projectContexts = CreateProjectContexts(projectPath.Value);
|
||||
|
||||
var projectContext = projectContexts.First();
|
||||
|
||||
var testRunner = projectContext.ProjectFile.TestRunner;
|
||||
|
||||
|
||||
if (portOption.HasValue())
|
||||
{
|
||||
int port;
|
||||
|
||||
|
||||
if (!Int32.TryParse(portOption.Value(), out port))
|
||||
{
|
||||
throw new InvalidOperationException($"{portOption.Value()} is not a valid port number.");
|
||||
|
@ -92,7 +92,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
|
||||
private static int RunConsole(ProjectContext projectContext, CommandLineApplication app, string testRunner)
|
||||
{
|
||||
var commandArgs = new List<string> {projectContext.GetAssemblyPath(Constants.DefaultConfiguration)};
|
||||
var commandArgs = new List<string> { projectContext.GetOutputPathCalculator().GetAssemblyPath(Constants.DefaultConfiguration) };
|
||||
commandArgs.AddRange(app.RemainingArguments);
|
||||
|
||||
return Command.Create($"{GetCommandName(testRunner)}", commandArgs, projectContext.TargetFramework)
|
||||
|
@ -171,7 +171,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
{
|
||||
TestHostTracing.Source.TraceInformation("Starting Discovery");
|
||||
|
||||
var commandArgs = new List<string> { projectContext.GetAssemblyPath(Constants.DefaultConfiguration) };
|
||||
var commandArgs = new List<string> { projectContext.GetOutputPathCalculator().GetAssemblyPath(Constants.DefaultConfiguration) };
|
||||
|
||||
commandArgs.AddRange(new[]
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
{
|
||||
TestHostTracing.Source.TraceInformation("Starting Execution");
|
||||
|
||||
var commandArgs = new List<string> { projectContext.GetAssemblyPath(Constants.DefaultConfiguration) };
|
||||
var commandArgs = new List<string> { projectContext.GetOutputPathCalculator().GetAssemblyPath(Constants.DefaultConfiguration) };
|
||||
|
||||
commandArgs.AddRange(new[]
|
||||
{
|
||||
|
@ -230,7 +230,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
|
||||
throw new InvalidOperationException(error);
|
||||
}
|
||||
|
||||
|
||||
private static void ExecuteRunnerCommand(string testRunner, ReportingChannel channel, List<string> commandArgs)
|
||||
{
|
||||
var result = Command.Create(GetCommandName(testRunner), commandArgs, new NuGetFramework("DNXCore", Version.Parse("5.0")))
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
"Newtonsoft.Json": "7.0.1"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnxcore50": {
|
||||
}
|
||||
"dnxcore50": { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
|
|||
var publishCommand = new PublishCommand(TestProject, output: OutputDirectory);
|
||||
publishCommand.Execute().Should().Pass();
|
||||
|
||||
TestOutputExecutable(OutputDirectory, publishCommand.GetOutputExecutable(), s_expectedOutput);
|
||||
TestExecutable(OutputDirectory, publishCommand.GetOutputExecutable(), s_expectedOutput);
|
||||
}
|
||||
|
||||
private void TestSetup()
|
||||
|
|
|
@ -75,12 +75,12 @@ namespace Microsoft.DotNet.Tools.Builder.Tests
|
|||
|
||||
protected static void AssertProjectSkipped(string skippedProject, CommandResult buildResult)
|
||||
{
|
||||
Assert.Contains($"Project {skippedProject} was previously compiled. Skipping compilation.", buildResult.StdOut, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Contains($"Project {skippedProject} (DNXCore,Version=v5.0) was previously compiled. Skipping compilation.", buildResult.StdOut, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
protected static void AssertProjectCompiled(string rebuiltProject, CommandResult buildResult)
|
||||
{
|
||||
Assert.Contains($"Project {rebuiltProject} will be compiled", buildResult.StdOut, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Contains($"Project {rebuiltProject} (DNXCore,Version=v5.0) will be compiled", buildResult.StdOut, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
protected string GetBinDirectory()
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Microsoft.DotNet.Tools.Builder.Tests
|
|||
Assert.False(File.Exists(lockFile));
|
||||
|
||||
buildResult = BuildProject(expectBuildFailure : true);
|
||||
Assert.Contains("does not have a lock file", buildResult.StdErr);
|
||||
Assert.Contains("does not have a lock file", buildResult.StdOut);
|
||||
}
|
||||
|
||||
[Fact(Skip="https://github.com/dotnet/cli/issues/980")]
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
|
|||
var buildCmd = new BuildCommand(testProject, output: outputDir);
|
||||
var result = buildCmd.ExecuteWithCapturedOutput();
|
||||
result.Should().Pass();
|
||||
Assert.Contains("CA1018", result.StdErr);
|
||||
Assert.Contains("CA1018", result.StdOut);
|
||||
}
|
||||
|
||||
private void CopyProjectToTempDir(string projectDir, TempDirectory tempDir)
|
||||
|
|
|
@ -152,7 +152,7 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
|
|||
|
||||
publishCommand.GetOutputDirectory().Should().HaveFile("TestLibraryWithRunner.dll");
|
||||
publishCommand.GetOutputDirectory().Should().HaveFile("TestLibraryWithRunner.pdb");
|
||||
publishCommand.GetOutputDirectory().Should().HaveFile("TestLibraryWithRunner.deps");
|
||||
publishCommand.GetOutputDirectory().Should().NotHaveFile("TestLibraryWithRunner.deps");
|
||||
publishCommand.GetOutputDirectory().Should().HaveFile("TestLibraryWithRunner.dll.config");
|
||||
// dependencies should also be copied
|
||||
publishCommand.GetOutputDirectory().Should().HaveFile("Newtonsoft.Json.dll");
|
||||
|
|
|
@ -61,8 +61,8 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
string framework = string.IsNullOrEmpty(_framework) ?
|
||||
_project.GetTargetFrameworks().First().FrameworkName.GetShortFolderName() : _framework;
|
||||
string runtime = string.IsNullOrEmpty(_runtime) ? PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier() : _runtime;
|
||||
//TODO: add runtime back as soon as it gets propagated through the various commands.
|
||||
string output = Path.Combine(config, framework);
|
||||
|
||||
string output = Path.Combine(config, framework, runtime);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
{
|
||||
if (!string.IsNullOrEmpty(_output))
|
||||
{
|
||||
return new DirectoryInfo(Path.Combine(_output, BuildRelativeOutputPath()));
|
||||
return new DirectoryInfo(_output);
|
||||
}
|
||||
|
||||
string output = Path.Combine(_project.ProjectDirectory, "bin", BuildRelativeOutputPath());
|
||||
|
|
|
@ -58,13 +58,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
string.Equals("on", val, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
protected void TestOutputExecutable(
|
||||
string outputDir,
|
||||
protected void TestExecutable(string outputDir,
|
||||
string executableName,
|
||||
string expectedOutput,
|
||||
bool native = false)
|
||||
string expectedOutput)
|
||||
{
|
||||
var executablePath = Path.Combine(GetCompilationOutputPath(outputDir, native), executableName);
|
||||
var executablePath = Path.Combine(outputDir, executableName);
|
||||
|
||||
var executableCommand = new TestCommand(executablePath);
|
||||
|
||||
|
@ -72,7 +70,16 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
|
||||
result.Should().HaveStdOut(expectedOutput);
|
||||
result.Should().NotHaveStdErr();
|
||||
result.Should().Pass();
|
||||
result.Should().Pass();
|
||||
}
|
||||
|
||||
protected void TestOutputExecutable(
|
||||
string outputDir,
|
||||
string executableName,
|
||||
string expectedOutput,
|
||||
bool native = false)
|
||||
{
|
||||
TestExecutable(GetCompilationOutputPath(outputDir, native), executableName, expectedOutput);
|
||||
}
|
||||
|
||||
protected void TestNativeOutputExecutable(string outputDir, string executableName, string expectedOutput)
|
||||
|
|
Loading…
Reference in a new issue