diff --git a/.gitignore b/.gitignore index c6692c567b33..37ef0f552f5c 100644 --- a/.gitignore +++ b/.gitignore @@ -181,4 +181,7 @@ project.json.template # Ignore Generated project template files Project.csproj -Project.vbproj \ No newline at end of file +Project.vbproj + +# VS Code +.vscode/ diff --git a/DotnetCLIVersion.txt b/DotnetCLIVersion.txt index f2e359f0b18b..22921e54bcbc 100644 --- a/DotnetCLIVersion.txt +++ b/DotnetCLIVersion.txt @@ -1 +1 @@ -1.0.0-rc4-004771 \ No newline at end of file +1.0.0-rc4-004828 \ No newline at end of file diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/App/App.csproj b/TestAssets/TestProjects/AppWithLibraryAndRid/App/App.csproj new file mode 100755 index 000000000000..65dc6d9782db --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/App/App.csproj @@ -0,0 +1,15 @@ + + + + Exe + netcoreapp1.0 + osx.10.11-x64;ubuntu.14.04-x64;win10-x64 + + + + + + + + + diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/App/Program.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/App/Program.cs new file mode 100755 index 000000000000..32764e35d63a --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/App/Program.cs @@ -0,0 +1,26 @@ +using System; + +namespace App +{ + class Program + { + static void Main(string[] args) + { + var libraryWithRidNativeOutput = LibraryWithRid.NativeCode.InvokeNativeCodeAndReturnAString(); + + var libraryWithRidsNativeOutput = LibraryWithRid.NativeCode.InvokeNativeCodeAndReturnAString(); + + var libraryWithRidCompileTimeRid = LibraryWithRid.NativeCode.GetRidStoredInAssemblyDescriptionAttribute(); + + var libraryWithRidsCompileTimeRid = LibraryWithRids.NativeCode.GetRidStoredInAssemblyDescriptionAttribute(); + + var libraryWithRidStatus = $"{libraryWithRidNativeOutput} {libraryWithRidCompileTimeRid}"; + + var libraryWithRidsStatus = $"{libraryWithRidsNativeOutput} {libraryWithRidsCompileTimeRid}"; + + var portableLibraryStatus = LibraryWithoutRid.PortableClass.GetHelloWorld(); + + Console.WriteLine($"{libraryWithRidStatus} {libraryWithRidsStatus} {portableLibraryStatus}"); + } + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/LibraryWithRid.csproj b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/LibraryWithRid.csproj new file mode 100755 index 000000000000..c7060fc094cb --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/LibraryWithRid.csproj @@ -0,0 +1,14 @@ + + + netstandard1.4 + $(TestRuntimeIdentifier) + + + '$(RuntimeIdentifier)' + + + + 3.13.0 + + + diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/LinuxNativeMethods.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/LinuxNativeMethods.cs new file mode 100644 index 000000000000..d9729d57ece6 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/LinuxNativeMethods.cs @@ -0,0 +1,11 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibraryWithRid +{ + public static class LinuxNativeMethods + { + [DllImport("libsqlite3", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr sqlite3_libversion(); + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/MacNativeMethods.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/MacNativeMethods.cs new file mode 100644 index 000000000000..b26a077f20a0 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/MacNativeMethods.cs @@ -0,0 +1,11 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibraryWithRid +{ + public static class MacNativeMethods + { + [DllImport("libsqlite3", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr sqlite3_libversion(); + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/NativeCode.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/NativeCode.cs new file mode 100755 index 000000000000..e5b4c89cafa4 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/NativeCode.cs @@ -0,0 +1,33 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace LibraryWithRid +{ + public class NativeCode + { + public static string InvokeNativeCodeAndReturnAString() + { + switch(GetRidStoredInAssemblyDescriptionAttribute()) + { + case "'ubuntu.14.04-x64'": + return Marshal.PtrToStringAnsi(LinuxNativeMethods.sqlite3_libversion()); + case "'osx.10.11-x64'": + return Marshal.PtrToStringAnsi(MacNativeMethods.sqlite3_libversion()); + case "'win10-x64'": + return Marshal.PtrToStringAnsi(WindowsNativeMethods.sqlite3_libversion()); + default: + return "Unexpected RID. Cannot find sqlite3."; + } + } + + public static string GetRidStoredInAssemblyDescriptionAttribute() + { + return typeof(NativeCode) + .GetTypeInfo() + .Assembly + .GetCustomAttribute() + ?.Description; + } + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/WindowsNativeMethods.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/WindowsNativeMethods.cs new file mode 100644 index 000000000000..38dd3be89be8 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRid/WindowsNativeMethods.cs @@ -0,0 +1,11 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibraryWithRid +{ + public static class WindowsNativeMethods + { + [DllImport("sqlite3", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr sqlite3_libversion(); + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/LibraryWithRids.csproj b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/LibraryWithRids.csproj new file mode 100755 index 000000000000..e4cc0d3ae54c --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/LibraryWithRids.csproj @@ -0,0 +1,12 @@ + + + netstandard1.4 + osx.10.11-x64;ubuntu.14.04-x64;win10-x64 + '$(RuntimeIdentifier)' + + + + 3.13.0 + + + diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/LinuxNativeMethods.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/LinuxNativeMethods.cs new file mode 100644 index 000000000000..a6c1db7dea45 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/LinuxNativeMethods.cs @@ -0,0 +1,11 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibraryWithRids +{ + public static class LinuxNativeMethods + { + [DllImport("libsqlite3", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr sqlite3_libversion(); + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/MacNativeMethods.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/MacNativeMethods.cs new file mode 100644 index 000000000000..7aa87faf5256 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/MacNativeMethods.cs @@ -0,0 +1,11 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibraryWithRids +{ + public static class MacNativeMethods + { + [DllImport("libsqlite3", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr sqlite3_libversion(); + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/NativeCode.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/NativeCode.cs new file mode 100755 index 000000000000..36b4a900b96c --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/NativeCode.cs @@ -0,0 +1,33 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace LibraryWithRids +{ + public class NativeCode + { + public static string InvokeNativeCodeAndReturnAString() + { + switch(GetRidStoredInAssemblyDescriptionAttribute()) + { + case "'ubuntu.14.04-x64'": + return Marshal.PtrToStringAnsi(LinuxNativeMethods.sqlite3_libversion()); + case "'osx.10.11-x64'": + return Marshal.PtrToStringAnsi(MacNativeMethods.sqlite3_libversion()); + case "'win10-x64'": + return Marshal.PtrToStringAnsi(WindowsNativeMethods.sqlite3_libversion()); + default: + return "Unexpected RID. Cannot find sqlite3."; + } + } + + public static string GetRidStoredInAssemblyDescriptionAttribute() + { + return typeof(NativeCode) + .GetTypeInfo() + .Assembly + .GetCustomAttribute() + ?.Description; + } + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/WindowsNativeMethods.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/WindowsNativeMethods.cs new file mode 100644 index 000000000000..f8f6f8b1838b --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithRids/WindowsNativeMethods.cs @@ -0,0 +1,11 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibraryWithRids +{ + public static class WindowsNativeMethods + { + [DllImport("sqlite3", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr sqlite3_libversion(); + } +} diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithoutRid/LibraryWithoutRid.csproj b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithoutRid/LibraryWithoutRid.csproj new file mode 100755 index 000000000000..b290d67fb724 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithoutRid/LibraryWithoutRid.csproj @@ -0,0 +1,7 @@ + + + + netstandard1.4 + + + diff --git a/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithoutRid/PortableCode.cs b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithoutRid/PortableCode.cs new file mode 100755 index 000000000000..d90d7b5ee7e0 --- /dev/null +++ b/TestAssets/TestProjects/AppWithLibraryAndRid/LibraryWithoutRid/PortableCode.cs @@ -0,0 +1,12 @@ +using System; + +namespace LibraryWithoutRid +{ + public class PortableClass + { + public static string GetHelloWorld() + { + return "Hello World"; + } + } +} diff --git a/build/build.proj b/build/build.proj index c074ab4c7341..cf902eb3571a 100644 --- a/build/build.proj +++ b/build/build.proj @@ -164,6 +164,7 @@ DestinationFolder="$(TestsDirectory)" /> + - + + + <_IsRidAgnostic>false + <_IsRidAgnostic Condition=" '$(RuntimeIdentifier)' == '' and '$(RuntimeIdentifiers)' == '' ">true + <_SkipNearestTargetFrameworkResolution Condition="'$(TargetFramework)' != '' and '$(ReferringTargetFramework)' == ''">true $(TargetFramework) diff --git a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildASelfContainedAppWithRid.cs b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildASelfContainedAppWithRid.cs new file mode 100644 index 000000000000..fe0367d1d9c1 --- /dev/null +++ b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildASelfContainedAppWithRid.cs @@ -0,0 +1,61 @@ +// 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 FluentAssertions; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.InternalAbstractions; +using Microsoft.NET.TestFramework; +using Microsoft.NET.TestFramework.Commands; +using Microsoft.NET.TestFramework.Assertions; +using System.IO; +using Xunit; +using static Microsoft.NET.TestFramework.Commands.MSBuildTest; + +namespace Microsoft.NET.Build.Tests +{ + public class GivenThatWeWantToBuildASelfContainedAppWithLibrariesAndRid : SdkTest + { + [Fact] + public void It_builds_a_RID_specific_runnable_output() + { + if (UsingFullFrameworkMSBuild) + { + // Disable this test on full framework, as the current build won't have access to + // https://github.com/Microsoft/msbuild/pull/1674 + // See https://github.com/dotnet/sdk/issues/877 + return; + } + + var runtimeIdentifier = RuntimeEnvironment.GetRuntimeIdentifier(); + var testAsset = _testAssetsManager + .CopyTestAsset("AppWithLibraryAndRid") + .WithSource(); + + var projectPath = Path.Combine(testAsset.TestRoot, "App"); + + var restoreCommand = new RestoreCommand(Stage0MSBuild, projectPath, "App.csproj"); + restoreCommand + .Execute($"/p:TestRuntimeIdentifier={runtimeIdentifier}") + .Should() + .Pass(); + + var buildCommand = new BuildCommand(Stage0MSBuild, projectPath); + + buildCommand + .Execute($"/p:RuntimeIdentifier={runtimeIdentifier}", $"/p:TestRuntimeIdentifier={runtimeIdentifier}") + .Should() + .Pass(); + + var outputDirectory = buildCommand.GetOutputDirectory("netcoreapp1.0"); + var selfContainedExecutable = $"App{Constants.ExeSuffix}"; + + Command.Create(Path.Combine(outputDirectory.FullName, selfContainedExecutable), new string[] { }) + .CaptureStdOut() + .Execute() + .Should() + .Pass() + .And + .HaveStdOutContaining($"3.13.0 '{runtimeIdentifier}' 3.13.0 '{runtimeIdentifier}' Hello World"); + } + } +}