diff --git a/Directory.Build.props b/Directory.Build.props index 35aaa6a2ae..d7c5acd6b0 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -70,6 +70,10 @@ Microsoft.AspNetCore.App Shared Framework for hosting of Microsoft ASP.NET Core applications. It is open source, cross-platform and is supported by Microsoft. We hope you enjoy using it! If you do, please consider joining the active community of developers that are contributing to the project on GitHub ($(RepositoryUrl)). We happily accept issues and PRs. + .NETCoreApp + netcoreapp$(AspNetCoreMajorMinorVersion) + ASP.NET Core $(AspNetCoreMajorMinorVersion) + Microsoft.AspNetCore.App.Ref aspnetcore-runtime aspnetcore-targeting-pack diff --git a/eng/tools/RepoTasks/CreateFrameworkListFile.cs b/eng/tools/RepoTasks/CreateFrameworkListFile.cs new file mode 100644 index 0000000000..b0ab8c690a --- /dev/null +++ b/eng/tools/RepoTasks/CreateFrameworkListFile.cs @@ -0,0 +1,107 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace RepoTasks +{ + public class CreateFrameworkListFile : Task + { + /// + /// Files to extract basic information from and include in the list. + /// + [Required] + public ITaskItem[] Files { get; set; } + + [Required] + public string TargetFile { get; set; } + + /// + /// Extra attributes to place on the root node. + /// + /// %(Identity): Attribute name. + /// %(Value): Attribute value. + /// + public ITaskItem[] RootAttributes { get; set; } + + public override bool Execute() + { + XAttribute[] rootAttributes = RootAttributes + ?.Select(item => new XAttribute(item.ItemSpec, item.GetMetadata("Value"))) + .ToArray(); + + var frameworkManifest = new XElement("FileList", rootAttributes); + + var usedFileProfiles = new HashSet(); + + foreach (var f in Files + .Select(item => new + { + Item = item, + Filename = Path.GetFileName(item.ItemSpec), + TargetPath = item.GetMetadata("TargetPath"), + AssemblyName = FileUtilities.GetAssemblyName(item.ItemSpec), + FileVersion = FileUtilities.GetFileVersion(item.ItemSpec), + IsNative = item.GetMetadata("IsNativeImage") == "true", + IsSymbolFile = item.GetMetadata("IsSymbolFile") == "true" + }) + .Where(f => + !f.IsSymbolFile && + (f.Filename.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || f.IsNative)) + .OrderBy(f => f.TargetPath, StringComparer.Ordinal) + .ThenBy(f => f.Filename, StringComparer.Ordinal)) + { + var element = new XElement( + "File", + new XAttribute("Type", f.IsNative ? "Native" : "Managed"), + new XAttribute( + "Path", + Path.Combine(f.TargetPath, f.Filename).Replace('\\', '/'))); + + if (f.AssemblyName != null) + { + byte[] publicKeyToken = f.AssemblyName.GetPublicKeyToken(); + string publicKeyTokenHex; + + if (publicKeyToken != null) + { + publicKeyTokenHex = BitConverter.ToString(publicKeyToken) + .ToLowerInvariant() + .Replace("-", ""); + } + else + { + Log.LogError($"No public key token found for assembly {f.Item.ItemSpec}"); + publicKeyTokenHex = ""; + } + + element.Add( + new XAttribute("AssemblyName", f.AssemblyName.Name), + new XAttribute("PublicKeyToken", publicKeyTokenHex), + new XAttribute("AssemblyVersion", f.AssemblyName.Version)); + } + else if (!f.IsNative) + { + // This file isn't managed and isn't native. Leave it off the list. + continue; + } + + element.Add(new XAttribute("FileVersion", f.FileVersion)); + + frameworkManifest.Add(element); + } + + Directory.CreateDirectory(Path.GetDirectoryName(TargetFile)); + File.WriteAllText(TargetFile, frameworkManifest.ToString()); + + return !Log.HasLoggedErrors; + } + } +} diff --git a/eng/tools/RepoTasks/FileUtilities.cs b/eng/tools/RepoTasks/FileUtilities.cs index ecb20bfc0f..b384cbe5e2 100644 --- a/eng/tools/RepoTasks/FileUtilities.cs +++ b/eng/tools/RepoTasks/FileUtilities.cs @@ -7,41 +7,42 @@ using System.Diagnostics; using System.IO; using System.Reflection; -namespace Microsoft.DotNet.Build.Tasks +namespace RepoTasks { - internal static class FileUtilities + internal static partial class FileUtilities { + private static readonly HashSet s_assemblyExtensions = new HashSet( + new[] { ".dll", ".exe", ".winmd" }, + StringComparer.OrdinalIgnoreCase); + public static Version GetFileVersion(string sourcePath) { var fvi = FileVersionInfo.GetVersionInfo(sourcePath); - return fvi != null - ? new Version(fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart) - : null; + if (fvi != null) + { + return new Version(fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart); + } + + return null; } - private static readonly HashSet _assemblyExtensions = new HashSet(new[] { ".dll", ".exe", ".winmd" }, StringComparer.OrdinalIgnoreCase); - - public static Version TryGetAssemblyVersion(string sourcePath) + public static AssemblyName GetAssemblyName(string path) { - var extension = Path.GetExtension(sourcePath); + if (!s_assemblyExtensions.Contains(Path.GetExtension(path))) + { + return null; + } - return _assemblyExtensions.Contains(extension) - ? GetAssemblyVersion(sourcePath) - : null; - } - - private static Version GetAssemblyVersion(string sourcePath) - { try { - return AssemblyName.GetAssemblyName(sourcePath)?.Version; + return AssemblyName.GetAssemblyName(path); } catch (BadImageFormatException) { - // If an .dll file cannot be read, it may be a native .dll which would not have an assembly version. + // Not a valid assembly. return null; } } } -} +} \ No newline at end of file diff --git a/eng/tools/RepoTasks/GenerateSharedFrameworkDepsFile.cs b/eng/tools/RepoTasks/GenerateSharedFrameworkDepsFile.cs index a4022e7491..172f002d18 100644 --- a/eng/tools/RepoTasks/GenerateSharedFrameworkDepsFile.cs +++ b/eng/tools/RepoTasks/GenerateSharedFrameworkDepsFile.cs @@ -10,7 +10,6 @@ using System.Reflection; using System.Text; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; -using Microsoft.DotNet.Build.Tasks; using Microsoft.Extensions.DependencyModel; namespace RepoTasks @@ -61,7 +60,7 @@ namespace RepoTasks var filePath = reference.ItemSpec; var fileName = Path.GetFileName(filePath); var fileVersion = FileUtilities.GetFileVersion(filePath)?.ToString() ?? string.Empty; - var assemblyVersion = FileUtilities.TryGetAssemblyVersion(filePath); + var assemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version; if (assemblyVersion == null) { var nativeFile = new RuntimeFile(fileName, null, fileVersion); diff --git a/eng/tools/RepoTasks/RepoTasks.tasks b/eng/tools/RepoTasks/RepoTasks.tasks index e8a24ee1f3..b55f394e4c 100644 --- a/eng/tools/RepoTasks/RepoTasks.tasks +++ b/eng/tools/RepoTasks/RepoTasks.tasks @@ -8,5 +8,6 @@ + diff --git a/src/Framework/Directory.Build.props b/src/Framework/Directory.Build.props index 8cf57408e3..2a8b3bf3c0 100644 --- a/src/Framework/Directory.Build.props +++ b/src/Framework/Directory.Build.props @@ -8,4 +8,11 @@ $(ArtifactsObjDir)$(PlatformManifestFileName) + + + + + + + diff --git a/src/Framework/build.cmd b/src/Framework/build.cmd new file mode 100644 index 0000000000..2406296662 --- /dev/null +++ b/src/Framework/build.cmd @@ -0,0 +1,3 @@ +@ECHO OFF +SET RepoRoot=%~dp0..\.. +%RepoRoot%\build.cmd -projects %~dp0**\*.*proj %* diff --git a/src/Framework/ref/Microsoft.AspNetCore.App.Ref.csproj b/src/Framework/ref/Microsoft.AspNetCore.App.Ref.csproj index 6e2ca3f924..2a73d0fb44 100644 --- a/src/Framework/ref/Microsoft.AspNetCore.App.Ref.csproj +++ b/src/Framework/ref/Microsoft.AspNetCore.App.Ref.csproj @@ -36,6 +36,10 @@ This package is an internal implementation of the .NET Core SDK and is not meant true + + + FrameworkList.xml + $(ArtifactsObjDir)$(FrameworkListFileName) @@ -67,6 +71,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant $(BuildDependsOn); GeneratePackageConflictManifest; _ResolveTargetingPackContent; + IncludeFrameworkListFile; _BatchCopyToLayoutTargetDir; _InstallTargetingPackIntoLocalDotNet; _CreateTargetingPackArchive; @@ -113,8 +118,6 @@ This package is an internal implementation of the .NET Core SDK and is not meant - - <_PackageFiles Include="@(RefPackContent)" /> @@ -174,4 +177,19 @@ This package is an internal implementation of the .NET Core SDK and is not meant + + + + + + <_PackageFiles Include="@(RefPackContent)" /> + + + diff --git a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj index c8a6be74e9..034b037393 100644 --- a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj +++ b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj @@ -100,6 +100,9 @@ This package is an internal implementation of the .NET Core SDK and is not meant $([MSBuild]::EnsureTrailingSlash('$(RuntimePackageRoot)')) $([System.IO.Path]::Combine('$(RuntimePackageRoot)', 'tools', '$(CrossgenToolPackagePath)')) $(AssetTargetFallback);native,Version=0.0 + + RuntimeList.xml + $(ArtifactsObjDir)$(FrameworkListFileName) @@ -154,6 +157,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant GenerateSharedFxVersionsFiles; Crossgen; _ResolveSharedFrameworkContent; + IncludeFrameworkListFile; _DownloadAndExtractDotNetRuntime; _BatchCopyToSharedFrameworkLayout; _BatchCopyToRedistLayout; @@ -275,8 +279,6 @@ This package is an internal implementation of the .NET Core SDK and is not meant DependsOnTargets="GenerateSharedFxDepsFile"> - - <_PackageFiles Include="@(RuntimePackContent)" /> @@ -448,4 +450,19 @@ This package is an internal implementation of the .NET Core SDK and is not meant Condition="'$(ArchiveExtension)' == '.tar.gz'" /> + + + + + + <_PackageFiles Include="@(RuntimePackContent)" /> + + +