From a25e92208e21c4b6273d424b1b66dcb352d70dd5 Mon Sep 17 00:00:00 2001 From: Bryan Date: Fri, 29 Apr 2016 15:54:47 -0700 Subject: [PATCH 1/2] fixes #2760 Verify coreclr absence/presence depending on app type during dotnet build. --- .../PortableApp_Standalone/.noautobuild} | 0 .../PortableApp_Standalone/Program.cs | 12 +++++++++ .../PortableApp_Standalone/project.json | 17 ++++++++++++ .../project.json.modified | 26 +++++++++++++++++++ .../StandaloneApp_Portable/.noautobuild | 0 .../StandaloneApp_Portable/Program.cs | 12 +++++++++ .../StandaloneApp_Portable/project.json | 22 ++++++++++++++++ .../project.json.modified | 25 ++++++++++++++++++ src/Microsoft.DotNet.Cli.Utils/Constants.cs | 7 +++++ .../Executable.cs | 23 ++++++++++++++-- .../dotnet-build/DotnetProjectBuilder.cs | 2 +- test/dotnet-build.Tests/BuildOutputTests.cs | 24 +++++++++++++++++ 12 files changed, 167 insertions(+), 3 deletions(-) rename TestAssets/{CrossPublishTestProjects/StandaloneAppCrossPublish/project.json => TestProjects/DependencyChangeTest/PortableApp_Standalone/.noautobuild} (100%) create mode 100644 TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/Program.cs create mode 100644 TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json create mode 100644 TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json.modified create mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/.noautobuild create mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs create mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json create mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified diff --git a/TestAssets/CrossPublishTestProjects/StandaloneAppCrossPublish/project.json b/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/.noautobuild similarity index 100% rename from TestAssets/CrossPublishTestProjects/StandaloneAppCrossPublish/project.json rename to TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/.noautobuild diff --git a/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/Program.cs b/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/Program.cs new file mode 100644 index 000000000..fbe8e9b0e --- /dev/null +++ b/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace PortableApp +{ + public static class Program + { + public static void Main(string[] args) + { + Console.WriteLine("Hello, World!"); + } + } +} diff --git a/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json b/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json new file mode 100644 index 000000000..8065921be --- /dev/null +++ b/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json @@ -0,0 +1,17 @@ +{ + "compilationOptions": { + "emitEntryPoint": true + }, + "dependencies": {}, + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0-rc2-*" + } + } + } + } +} + diff --git a/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json.modified b/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json.modified new file mode 100644 index 000000000..b80ab80b6 --- /dev/null +++ b/TestAssets/TestProjects/DependencyChangeTest/PortableApp_Standalone/project.json.modified @@ -0,0 +1,26 @@ +{ + "compilationOptions": { + "emitEntryPoint": true + }, + "dependencies": {}, + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.0.0-rc2-*" + } + } + } + }, + + "runtimes": { + "win7-x64": {}, + "win7-x86": {}, + "osx.10.10-x64": {}, + "osx.10.11-x64": {}, + "ubuntu.14.04-x64": {}, + "centos.7-x64": {}, + "rhel.7.2-x64": {}, + "debian.8-x64": {} + } +} diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/.noautobuild b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs new file mode 100644 index 000000000..529893b0e --- /dev/null +++ b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace StandaloneApp +{ + public static class Program + { + public static void Main(string[] args) + { + Console.WriteLine("Hello, World!"); + } + } +} diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json new file mode 100644 index 000000000..95649a930 --- /dev/null +++ b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json @@ -0,0 +1,22 @@ +{ + "compilationOptions": { + "emitEntryPoint": true + }, + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": "1.0.0-rc2-*" + } + } + }, + "runtimes": { + "win7-x64": {}, + "win7-x86": {}, + "osx.10.10-x64": {}, + "osx.10.11-x64": {}, + "ubuntu.14.04-x64": {}, + "centos.7-x64": {}, + "rhel.7.2-x64": {}, + "debian.8-x64": {} + } +} diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified new file mode 100644 index 000000000..3f57fac5f --- /dev/null +++ b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified @@ -0,0 +1,25 @@ +{ + "compilationOptions": { + "emitEntryPoint": true + }, + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0-rc2-*" + } + } + } + }, + "runtimes": { + "win7-x64": {}, + "win7-x86": {}, + "osx.10.10-x64": {}, + "osx.10.11-x64": {}, + "ubuntu.14.04-x64": {}, + "centos.7-x64": {}, + "rhel.7.2-x64": {}, + "debian.8-x64": {} + } +} diff --git a/src/Microsoft.DotNet.Cli.Utils/Constants.cs b/src/Microsoft.DotNet.Cli.Utils/Constants.cs index 1d10032ab..fa4dfb349 100644 --- a/src/Microsoft.DotNet.Cli.Utils/Constants.cs +++ b/src/Microsoft.DotNet.Cli.Utils/Constants.cs @@ -43,5 +43,12 @@ namespace Microsoft.DotNet.Cli.Utils (CurrentPlatform == Platform.Windows ? "hostfxr" : "libhostfxr") + DynamicLibSuffix }; + public static readonly string[] LibCoreClrBinaryNames = new string[] + { + "coreclr.dll", + "libcoreclr.so", + "libcoreclr.dylib" + }; + } } diff --git a/src/Microsoft.DotNet.Compiler.Common/Executable.cs b/src/Microsoft.DotNet.Compiler.Common/Executable.cs index 104c5fdc5..0ad3a7f97 100644 --- a/src/Microsoft.DotNet.Compiler.Common/Executable.cs +++ b/src/Microsoft.DotNet.Compiler.Common/Executable.cs @@ -56,6 +56,23 @@ namespace Microsoft.DotNet.Cli.Compiler.Common ExportRuntimeAssets(); } + private void VerifyCoreclrPresenceInPackageGraph() + { + var isCoreclrPresent = _exporter + .GetAllExports() + .SelectMany(e => e.NativeLibraryGroups) + .SelectMany(g => g.Assets) + .Select(a => a.FileName) + .Where(f => Constants.LibCoreClrBinaryNames.Contains(f)) + .Any(); + + // coreclr should be present for standalone apps + if (! isCoreclrPresent) + { + throw new InvalidOperationException("Expected coreclr library not found in package graph. Please try running restore again."); + } + } + private void ExportRuntimeAssets() { if (_context.TargetFramework.IsDesktop()) @@ -77,13 +94,15 @@ namespace Microsoft.DotNet.Cli.Compiler.Common } private void MakeCompilationOutputRunnableForCoreCLR() - { + { WriteDepsFileAndCopyProjectDependencies(_exporter); var emitEntryPoint = _compilerOptions.EmitEntryPoint ?? false; - if (emitEntryPoint && !string.IsNullOrEmpty(_context.RuntimeIdentifier)) + + if (emitEntryPoint && !_context.IsPortable) { // TODO: Pick a host based on the RID + VerifyCoreclrPresenceInPackageGraph(); CoreHost.CopyTo(_runtimeOutputPath, _compilerOptions.OutputName + Constants.ExeSuffix); } } diff --git a/src/dotnet/commands/dotnet-build/DotnetProjectBuilder.cs b/src/dotnet/commands/dotnet-build/DotnetProjectBuilder.cs index d43a88f14..9333c15a6 100644 --- a/src/dotnet/commands/dotnet-build/DotnetProjectBuilder.cs +++ b/src/dotnet/commands/dotnet-build/DotnetProjectBuilder.cs @@ -129,7 +129,7 @@ namespace Microsoft.DotNet.Tools.Build } catch (Exception e) { - throw new Exception($"Failed to make the following project runnable: {graphNode.ProjectContext.GetDisplayName()}", e); + throw new Exception($"Failed to make the following project runnable: {graphNode.ProjectContext.GetDisplayName()} reason: {e.Message}", e); } } diff --git a/test/dotnet-build.Tests/BuildOutputTests.cs b/test/dotnet-build.Tests/BuildOutputTests.cs index 1e97eb5fa..a34d47208 100644 --- a/test/dotnet-build.Tests/BuildOutputTests.cs +++ b/test/dotnet-build.Tests/BuildOutputTests.cs @@ -307,6 +307,30 @@ namespace Microsoft.DotNet.Tools.Builder.Tests } } + + [Fact] + private void StandaloneApp_WithoutCoreclrDll_Fails() + { + // Convert a Portable App to Standalone to simulate the customer scenario + var testInstance = TestAssetsManager.CreateTestInstance("DependencyChangeTest") + .WithLockFiles(); + + // Convert the portable test project to standalone by removing "type": "platform" and adding rids + var originalTestProject = Path.Combine(testInstance.TestRoot, "PortableApp_Standalone", "project.json"); + var modifiedTestProject = Path.Combine(testInstance.TestRoot, "PortableApp_Standalone", "project.json.modified"); + + // Simulate a user editting the project.json + File.Delete(originalTestProject); + File.Copy(modifiedTestProject, originalTestProject); + + var buildResult = new BuildCommand(originalTestProject, framework: DefaultFramework) + .ExecuteWithCapturedOutput(); + + buildResult.Should().Fail(); + + buildResult.StdErr.Should().Contain("Expected coreclr library not found in package graph. Please try running restore again."); + } + private void CopyProjectToTempDir(string projectDir, TempDirectory tempDir) { // copy all the files to temp dir From 25335d20fea6fac9d59236e8d216289d3f23391a Mon Sep 17 00:00:00 2001 From: Bryan Thornbury Date: Tue, 3 May 2016 11:33:13 -0700 Subject: [PATCH 2/2] PR Feedback --- .../StandaloneApp_Portable/.noautobuild | 0 .../StandaloneApp_Portable/Program.cs | 12 --------- .../StandaloneApp_Portable/project.json | 22 ---------------- .../project.json.modified | 25 ------------------- .../Executable.cs | 10 ++++---- test/dotnet-build.Tests/BuildOutputTests.cs | 4 +-- 6 files changed, 7 insertions(+), 66 deletions(-) delete mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/.noautobuild delete mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs delete mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json delete mode 100644 TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/.noautobuild b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/.noautobuild deleted file mode 100644 index e69de29bb..000000000 diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs deleted file mode 100644 index 529893b0e..000000000 --- a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace StandaloneApp -{ - public static class Program - { - public static void Main(string[] args) - { - Console.WriteLine("Hello, World!"); - } - } -} diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json deleted file mode 100644 index 95649a930..000000000 --- a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilationOptions": { - "emitEntryPoint": true - }, - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": "1.0.0-rc2-*" - } - } - }, - "runtimes": { - "win7-x64": {}, - "win7-x86": {}, - "osx.10.10-x64": {}, - "osx.10.11-x64": {}, - "ubuntu.14.04-x64": {}, - "centos.7-x64": {}, - "rhel.7.2-x64": {}, - "debian.8-x64": {} - } -} diff --git a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified b/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified deleted file mode 100644 index 3f57fac5f..000000000 --- a/TestAssets/TestProjects/DependencyChangeTest/StandaloneApp_Portable/project.json.modified +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilationOptions": { - "emitEntryPoint": true - }, - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.0-rc2-*" - } - } - } - }, - "runtimes": { - "win7-x64": {}, - "win7-x86": {}, - "osx.10.10-x64": {}, - "osx.10.11-x64": {}, - "ubuntu.14.04-x64": {}, - "centos.7-x64": {}, - "rhel.7.2-x64": {}, - "debian.8-x64": {} - } -} diff --git a/src/Microsoft.DotNet.Compiler.Common/Executable.cs b/src/Microsoft.DotNet.Compiler.Common/Executable.cs index 0ad3a7f97..69414a293 100644 --- a/src/Microsoft.DotNet.Compiler.Common/Executable.cs +++ b/src/Microsoft.DotNet.Compiler.Common/Executable.cs @@ -56,9 +56,9 @@ namespace Microsoft.DotNet.Cli.Compiler.Common ExportRuntimeAssets(); } - private void VerifyCoreclrPresenceInPackageGraph() + private void VerifyCoreClrPresenceInPackageGraph() { - var isCoreclrPresent = _exporter + var isCoreClrPresent = _exporter .GetAllExports() .SelectMany(e => e.NativeLibraryGroups) .SelectMany(g => g.Assets) @@ -67,9 +67,9 @@ namespace Microsoft.DotNet.Cli.Compiler.Common .Any(); // coreclr should be present for standalone apps - if (! isCoreclrPresent) + if (! isCoreClrPresent) { - throw new InvalidOperationException("Expected coreclr library not found in package graph. Please try running restore again."); + throw new InvalidOperationException("Expected coreclr library not found in package graph. Please try running dotnet restore again."); } } @@ -102,7 +102,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common if (emitEntryPoint && !_context.IsPortable) { // TODO: Pick a host based on the RID - VerifyCoreclrPresenceInPackageGraph(); + VerifyCoreClrPresenceInPackageGraph(); CoreHost.CopyTo(_runtimeOutputPath, _compilerOptions.OutputName + Constants.ExeSuffix); } } diff --git a/test/dotnet-build.Tests/BuildOutputTests.cs b/test/dotnet-build.Tests/BuildOutputTests.cs index a34d47208..bfdddd4de 100644 --- a/test/dotnet-build.Tests/BuildOutputTests.cs +++ b/test/dotnet-build.Tests/BuildOutputTests.cs @@ -309,7 +309,7 @@ namespace Microsoft.DotNet.Tools.Builder.Tests } [Fact] - private void StandaloneApp_WithoutCoreclrDll_Fails() + private void StandaloneApp_WithoutCoreClrDll_Fails() { // Convert a Portable App to Standalone to simulate the customer scenario var testInstance = TestAssetsManager.CreateTestInstance("DependencyChangeTest") @@ -328,7 +328,7 @@ namespace Microsoft.DotNet.Tools.Builder.Tests buildResult.Should().Fail(); - buildResult.StdErr.Should().Contain("Expected coreclr library not found in package graph. Please try running restore again."); + buildResult.StdErr.Should().Contain("Expected coreclr library not found in package graph. Please try running dotnet restore again."); } private void CopyProjectToTempDir(string projectDir, TempDirectory tempDir)