From 72181d394905d8038751ec4ea9a360a2d9eeb5a6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 28 May 2020 16:08:22 -0700 Subject: [PATCH 01/46] Version 5.0.0-dev.20326.3 Start working on a new SharedFramework SDK tooling story to unify between the dotnet/runtime, dotnet/windowsdesktop, and dotnet/aspnetcore shared framework authoring stories. After ReadyToRun, filter the itemgroup down to the files to bundle in the shared framework. Produce deps.json file for the shared framework. Various fixes found through local testing. Add support for resource assemblies. Fix multi-rid build. Fix typo Produce runtimeconfig.json. Copy over the CreateFrameworkListFile task to enable writing a FrameworkList.xml or RuntimeList.xml for their respective shared framework packs. Require the consumer to provide a package overrides file since all known customers already have their own mechanism to supply one. Implement templated platform manifest generation. Remove unused static. Re-enable publishing R2R symbols. Use GetFilesToPackage classifications for AppHost packs as well. Ensure that we don't include our generated files in the platform manifest check. Clean up error handling in GeneratePlatformManifestEntriesFromTemplate. Implement harvesting platform manifest support so shared frameworks that can use it don't need to use the templating approach. Implement dumping the completed shared framework to disk. Add back acquiring NuGet since we're going to need that when producing packages. Implement creating a compressed archive of the shared framework based on the on-disk layout. Output archive to packages. Implement packing a shared framework using the .NET SDKs packing infra. Package symbol files in the symbol package. Implement conditionally creating a symbols archive. Copy over targets from the old shared framework SDK and enable opt-in generation of .msi installers. Additional cleanup and validation TBD. Update deb, rpm, pkg paths to depend on the correct variables. Update cross-arch msi builds to work in the new system. Convert installer targets to be a recursive setup to enable building multiple types of packages from one build. Wire up installer generation to the build. Set GenerateInstallers to true to generate installers for the platform. Add ability to pass scripts to the macOS pkgbuild invocation. Fix shared framework name. Update creating the VS insertion packages. Batch up the installer build project calls instead of serially calling MSBuild. Fix RPM targets enough to get to the rpmbuild invocation. Make some progress on producing deb packages with dotnet-deb-tool to validate the targets flow. Fix typo. Also, building .deb packages works! (WSL->Windows drives apparently can have issues) Move the underlying scripts of dotnet-deb-tool into the shared framework SDK. Include RPM template files in the SDK. Remove the package testing files. Fix packing. Fix installer versioning and naming. Change many of the private installer properties to be prefixed with an underscore to make it easier to understand which properties are private. Fix light command package drop location. Enable adding dependencies for debs and rpms created with the built-in infra. Allow a different name for installers vs the archive. Make Wix exe bundles buildable. Fix product band version wix variable. Implement MacOS bundle proj. Various fixes to get to the point of building packages in dotnet/windowsdesktop. Fix building installers for targeting packs. Fix VS insertion package generation. Fix wix acquisition Filter symbol files out of the implementation package. Fix binplacing of resource files when publishing to disk. Fix Wix installer branding. Remove outdated todo Enable servicing and rid-based skipping in the same (for servicing) or similar (for RIDs) mechanism as the old shared framework sdk. Avoid re-evaluating when calling into the PublishSharedFrameworkToDisk target to avoid parallel copy issues and reduce the amount of work MSBuild has to do. Hook in package label versioning with the Arcade versioning story. Remove completed TODO Pass through RepoRoot so Arcade doesn't try to find it from the package cache. Various fixes around templated manifests and symbol file discovery/packaging. Fix issues found when packaging the .NET runtime shared framework. Use MSBuild to automatically determine the relative path for symbols instead of requiring it to be manually updated. Implement changes needed to support the shared host installer. Enable features for building the hostfxr and host installers. Update branding. Preliminary fixes for the bundle installer. Detect perfmap files as symbol files. Make sure we publish to disk before building our deb/rpms. Enhance build invocation caching to also cache R2R and auxiliary file generation so each build only runs each target once. This removes instabiility with attempts to ready-to-run the shared framework simultaneously by enabling the MSBuild scheduler to only execute the targets once. Fix typos in macos bundle creation. Actually write the distribution file to disk. Pass brand name instead of shared framework friendly name. --- .gitattributes | 14 + Arcade.sln | 14 + ...icrosoft.DotNet.SharedFramework.Sdk.csproj | 45 ++ .../README.md | 3 + .../sdk/Sdk.props | 26 + .../sdk/Sdk.targets | 22 + .../src/BuildFPMToolPreReqs.cs | 352 ++++++++++++ .../src/CreateFrameworkListFile.cs | 227 ++++++++ .../src/CreateLightCommandPackageDrop.cs | 246 ++++++++ .../src/ExecWithRetries.cs | 116 ++++ .../src/FileUtilities.cs | 49 ++ .../src/GenerateCurrentVersion.cs | 148 +++++ .../src/GenerateGuidFromName.cs | 71 +++ .../src/GenerateJsonObjectString.cs | 145 +++++ .../src/GenerateMacOSDistributionFile.cs | 72 +++ .../src/GenerateMsiVersion.cs | 102 ++++ ...ratePlatformManifestEntriesFromFileList.cs | 47 ++ ...ratePlatformManifestEntriesFromTemplate.cs | 101 ++++ .../src/GenerateSharedFrameworkDepsFile.cs | 112 ++++ .../src/PlatformManifestEntry.cs | 13 + .../src/StabilizeWixFileId.cs | 106 ++++ ...otNet.SharedFramework.Sdk.MultiRid.targets | 92 +++ ...Microsoft.DotNet.SharedFramework.Sdk.props | 4 + ...crosoft.DotNet.SharedFramework.Sdk.targets | 211 +++++++ .../targets/acquisition/Directory.Build.props | 9 + .../acquisition/Directory.Build.targets | 14 + .../acquire-nuget-exe/acquire-nuget-exe.proj | 18 + .../acquisition/acquire-wix/acquire-wix.proj | 32 ++ .../targets/bundle.targets | 164 ++++++ .../package_files/debian/compat | 1 + .../package_files/debian/source/format | 1 + .../targets/deb-package-tool/package_tool.sh | 264 +++++++++ .../scripts/config_template_generator.py | 268 +++++++++ .../scripts/debian_build_lib.sh | 171 ++++++ .../scripts/extract_json_value.py | 65 +++ .../scripts/manpage_generator.py | 304 ++++++++++ .../deb-package-tool/setup/build_setup.sh | 21 + .../deb-package-tool/setup/test_setup.sh | 28 + .../templates/debian/changelog | 5 + .../deb-package-tool/templates/debian/control | 20 + .../templates/debian/copyright | 10 + .../deb-package-tool/templates/debian/rules | 12 + .../targets/installer.multirid.targets | 31 + .../targets/installer.props | 6 + .../targets/installer.targets | 492 ++++++++++++++++ .../targets/resources/dotnetbackground.png | Bin 0 -> 4601 bytes .../targets/rpm_templates/changelog | 2 + .../targets/rpm_templates/copyright | 8 + .../targets/sharedfx.props | 18 + .../targets/sharedfx.targets | 526 +++++++++++++++++ .../targets/windows/bundle/bundle.wxs | 85 +++ .../targets/windows/bundle/dummyEula.rtf | 237 ++++++++ .../targets/windows/eula.rtf | 97 ++++ .../windows/product/breadcrumbstorefolder.wxs | 38 ++ .../windows/product/product.common.wxi | 32 ++ .../targets/windows/product/product.wxs | 56 ++ .../targets/windows/product/provider.wxs | 9 + .../targets/windows/product/registrykeys.wxs | 23 + .../targets/windows/product/sharedfxdir.wxs | 10 + .../windows/product/werrelatedkeys.wxs | 52 ++ .../targets/windows/variables.wxi | 29 + .../vs/VS.Redist.Common.Component.nuspec.txt | 18 + .../targets/windows/wix.targets | 540 ++++++++++++++++++ 63 files changed, 6054 insertions(+) create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/README.md create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.props create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/BuildFPMToolPreReqs.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/ExecWithRetries.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateCurrentVersion.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateGuidFromName.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateJsonObjectString.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMacOSDistributionFile.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMsiVersion.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromFileList.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromTemplate.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/PlatformManifestEntry.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/StabilizeWixFileId.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.MultiRid.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.props create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-wix/acquire-wix.proj create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/bundle.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/compat create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/source/format create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_tool.sh create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/config_template_generator.py create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/debian_build_lib.sh create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/extract_json_value.py create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/manpage_generator.py create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/build_setup.sh create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/test_setup.sh create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/changelog create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/control create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/copyright create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/rules create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.multirid.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.props create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/resources/dotnetbackground.png create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/changelog create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/copyright create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/dummyEula.rtf create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/eula.rtf create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/breadcrumbstorefolder.wxs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.wxs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/provider.wxs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/registrykeys.wxs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/sharedfxdir.wxs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/werrelatedkeys.wxs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/vs/VS.Redist.Common.Component.nuspec.txt create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets diff --git a/.gitattributes b/.gitattributes index e53d317832e..36d15129144 100644 --- a/.gitattributes +++ b/.gitattributes @@ -47,3 +47,17 @@ ############################################################################### *.png binary *.snk binary + + +############################################################################### +# Set file behavior to: +# treat as text, lf line endings +############################################################################### +changelog text eol=lf +control text eol=lf +copyright text eol=lf +rules text eol=lf +format text eol=lf +compat text eol=lf +*.bats text eol=lf +*.1 text eol=lf diff --git a/Arcade.sln b/Arcade.sln index 11945b0e596..d398eecbba5 100644 --- a/Arcade.sln +++ b/Arcade.sln @@ -101,6 +101,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Helix.Sdk. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.AsmDiff", "src\Microsoft.DotNet.AsmDiff\Microsoft.DotNet.AsmDiff.csproj", "{FDCE3109-3EA0-4166-B6C0-BE7BB4196864}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.SharedFramework.Sdk", "src\Microsoft.DotNet.SharedFramework.Sdk\Microsoft.DotNet.SharedFramework.Sdk.csproj", "{9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -635,6 +637,18 @@ Global {FDCE3109-3EA0-4166-B6C0-BE7BB4196864}.Release|x64.Build.0 = Release|Any CPU {FDCE3109-3EA0-4166-B6C0-BE7BB4196864}.Release|x86.ActiveCfg = Release|Any CPU {FDCE3109-3EA0-4166-B6C0-BE7BB4196864}.Release|x86.Build.0 = Release|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Debug|x64.ActiveCfg = Debug|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Debug|x64.Build.0 = Debug|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Debug|x86.ActiveCfg = Debug|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Debug|x86.Build.0 = Debug|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Release|Any CPU.Build.0 = Release|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Release|x64.ActiveCfg = Release|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Release|x64.Build.0 = Release|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Release|x86.ActiveCfg = Release|Any CPU + {9EB0B2AE-C55C-4DEF-90B3-44E73F0A366D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj new file mode 100644 index 00000000000..ad7acb25026 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj @@ -0,0 +1,45 @@ + + + + net472;netcoreapp2.1 + preview + false + + true + + Common toolset for building shared frameworks and framework packs. + MSBuildSdk + + false + false + $(NoWarn);3021;NU5105 + + **/*.Desktop.* + + + + + + + + + + + + + + sdk/%(RecursiveDir)%(Filename)%(Extension) + + + targets + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md new file mode 100644 index 00000000000..eb2545dc910 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md @@ -0,0 +1,3 @@ +# Microsoft.DotNet.SharedFramework.Sdk + +Common toolset for building shared frameworks and framework packs. diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.props b/src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.props new file mode 100644 index 00000000000..a3dce90f91e --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.props @@ -0,0 +1,26 @@ + + + + + + $(MSBuildThisFileDirectory)../tools/netcoreapp2.1/ + $(MSBuildThisFileDirectory)../tools/net472/ + + + + $(DotNetSharedFrameworkTaskDir)Microsoft.DotNet.SharedFramework.Sdk.dll + + + + + $(MSBuildThisFileDirectory)..\targets\ + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.targets new file mode 100644 index 00000000000..235e499fdb0 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/sdk/Sdk.targets @@ -0,0 +1,22 @@ + + + + + + true + + + + <_DispatchMultiRidBuild Condition="'$(IsCrossTargetingBuild)' != 'true' or '$(IsCrossTargetedBuild)' == 'true'">$(IsMultiRidBuild) + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/BuildFPMToolPreReqs.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/BuildFPMToolPreReqs.cs new file mode 100644 index 00000000000..f6b519593f6 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/BuildFPMToolPreReqs.cs @@ -0,0 +1,352 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +{ + /// + /// This task prepares the command line parameters for running a RPM build using FPM tool and also updates the copyright and changelog file tokens. + /// If parses various values from the config json by first reading it into a model and then builds the required string for parameters and passes it back. + /// + /// + public class BuildFPMToolPreReqs : BuildTask + { + [Required] + public string InputDir { get; set; } + [Required] + public string OutputDir { get; set; } + [Required] + public string PackageVersion { get; set; } + [Required] + public string ConfigJsonFile { get; set; } + [Output] + public string FPMParameters { get; set; } + + public override bool Execute() + { + try + { + if (!File.Exists(ConfigJsonFile)) + { + throw new FileNotFoundException($"Expected file {ConfigJsonFile} was not found."); + } + + // Open the Config Json and read the values into the model + TextReader projectFileReader = File.OpenText(ConfigJsonFile); + if (projectFileReader != null) + { + string jsonFileText = projectFileReader.ReadToEnd(); + ConfigJson configJson = JsonConvert.DeserializeObject(jsonFileText); + + // Update the Changelog and Copyright files by replacing tokens with values from config json + UpdateChangelog(configJson, PackageVersion); + UpdateCopyRight(configJson); + + // Build the full list of parameters + FPMParameters = BuildCmdParameters(configJson, PackageVersion); + Log.LogMessage(LogImportance.Normal, "Generated RPM paramters: " + FPMParameters); + } + else + { + throw new IOException($"Could not open the file {ConfigJsonFile} for reading."); + } + } + catch (Exception e) + { + Log.LogErrorFromException(e, true); + } + + return !Log.HasLoggedErrors; + } + + // Update the tokens in the changelog file from the config Json + private void UpdateChangelog(ConfigJson configJson, string package_version) + { + try + { + string changelogFile = Path.Combine(InputDir, "templates", "changelog"); + if (!File.Exists(changelogFile)) + { + throw new FileNotFoundException($"Expected file {changelogFile} was not found."); + } + string str = File.ReadAllText(changelogFile); + str = str.Replace("{PACKAGE_NAME}", configJson.Package_Name); + str = str.Replace("{PACKAGE_VERSION}", package_version); + str = str.Replace("{PACKAGE_REVISION}", configJson.Release.Package_Revision); + str = str.Replace("{URGENCY}", configJson.Release.Urgency); + str = str.Replace("{CHANGELOG_MESSAGE}", configJson.Release.Changelog_Message); + str = str.Replace("{MAINTAINER_NAME}", configJson.Maintainer_Name); + str = str.Replace("{MAINTAINER_EMAIL}", configJson.Maintainer_Email); + // The date format needs to be like Wed May 17 2017 + str = str.Replace("{DATE}", DateTime.UtcNow.ToString("ddd MMM dd yyyy")); + File.WriteAllText(changelogFile, str); + } + catch (Exception e) + { + Log.LogError("Exception while updating the changelog file: " + e.Message); + } + } + + private void UpdateCopyRight(ConfigJson configJson) + { + try + { + // Update the tokens in the copyright file from the config Json + string copyrightFile = Path.Combine(InputDir, "templates", "copyright"); + if (!File.Exists(copyrightFile)) + { + throw new FileNotFoundException($"Expected file {copyrightFile} was not found."); + } + string str = File.ReadAllText(copyrightFile); + str = str.Replace("{COPYRIGHT_TEXT}", configJson.CopyRight); + str = str.Replace("{LICENSE_NAME}", configJson.License.Type); + str = str.Replace("{LICENSE_NAME}", configJson.License.Type); + str = str.Replace("{LICENSE_TEXT}", configJson.License.Full_Text); + File.WriteAllText(copyrightFile, str); + } + catch (Exception e) + { + Log.LogError("Exception while updating the copyright file: " + e.Message); + } + } + + private string BuildCmdParameters(ConfigJson configJson, string package_version) + { + // Parameter list that needs to be passed to FPM tool: + // -s : is the input source type(dir) --Static + // -t : is the type of package(rpm) --Static + // -n : is for the name of the package --JSON + // -v : is the version to give to the package --ARG + // -a : architecture --JSON + // -d : is for all dependent packages. This can be used multiple times to specify the dependencies of the package. --JSON + // --rpm-os : the operating system to target this rpm --Static + // --rpm-changelog : the changelog from FILEPATH contents --ARG + // --rpm-summary : it is the RPM summary that shows in the Title --JSON + // --description : it is the description for the package --JSON + // -p : The actual package name (with path) for your package. --ARG+JSON + // --conflicts : Other packages/versions this package conflicts with provided as CSV --JSON + // --directories : Recursively add directories as being owned by the package. --JSON + // --after-install : FILEPATH to the script to be run after install of the package --JSON + // --after-remove : FILEPATH to the script to be run after package removal --JSON + // --license : the licensing name for the package. This will include the license type in the meta-data for the package, but will not include the associated license file within the package itself. --JSON + // --iteration : the iteration to give to the package. This comes from the package_revision --JSON + // --url : url for this package. --JSON + // --verbose : Set verbose output for FPM tool --Static + // : Add all the folder mappings for packge_root, docs, man pages --Static + + var parameters = new List(); + parameters.Add("-s dir"); + parameters.Add("-t rpm"); + parameters.Add(string.Concat("-n ", configJson.Package_Name)); + parameters.Add(string.Concat("-v ", package_version)); + parameters.Add(string.Concat("-a ", configJson.Control.Architecture)); + + // Build the list of dependencies as -d -d + if (configJson.Rpm_Dependencies != null) + { + IEnumerable dependencies; + + switch (configJson.Rpm_Dependencies) + { + case JArray dependencyArray: + dependencies = dependencyArray.ToObject(); + break; + + case JObject dependencyDictionary: + dependencies = dependencyDictionary + .ToObject>() + .Select(pair => new RpmDependency + { + Package_Name = pair.Key, + Package_Version = pair.Value + }); + break; + + default: + throw new ArgumentException( + "Expected 'rpm_dependencies' to be JArray or JObject, but found " + + configJson.Rpm_Dependencies.Type); + } + + foreach (RpmDependency rpmdep in dependencies) + { + string dependency = ""; + if (rpmdep.Package_Name != "") + { + // If no version is specified then the dependency is just the package without >= check + if (rpmdep.Package_Version == "") + { + dependency = rpmdep.Package_Name; + } + else + { + dependency = string.Concat(rpmdep.Package_Name, " >= ", rpmdep.Package_Version); + } + } + if (dependency != "") + { + parameters.Add(string.Concat("-d ", EscapeArg(dependency))); + } + } + } + + // Build the list of owned directories + if (configJson.Directories != null) + { + foreach (string dir in configJson.Directories) + { + if (dir != "") + { + parameters.Add(string.Concat("--directories ", EscapeArg(dir))); + } + } + } + + parameters.Add("--rpm-os linux"); + parameters.Add(string.Concat("--rpm-changelog ", EscapeArg(Path.Combine(InputDir, "templates", "changelog")))); // Changelog File + parameters.Add(string.Concat("--rpm-summary ", EscapeArg(configJson.Short_Description))); + parameters.Add(string.Concat("--description ", EscapeArg(configJson.Long_Description))); + parameters.Add(string.Concat("--maintainer ", EscapeArg(configJson.Maintainer_Name + " <" + configJson.Maintainer_Email + ">"))); + parameters.Add(string.Concat("--vendor ", EscapeArg(configJson.Vendor))); + parameters.Add(string.Concat("-p ", Path.Combine(OutputDir, configJson.Package_Name + ".rpm"))); + if (configJson.Package_Conflicts != null) parameters.Add(string.Concat("--conflicts ", EscapeArg(string.Join(",", configJson.Package_Conflicts)))); + if (configJson.After_Install_Source != null) parameters.Add(string.Concat("--after-install ", Path.Combine(InputDir, EscapeArg(configJson.After_Install_Source)))); + if (configJson.After_Remove_Source != null) parameters.Add(string.Concat("--after-remove ", Path.Combine(InputDir, EscapeArg(configJson.After_Remove_Source)))); + parameters.Add(string.Concat("--license ", EscapeArg(configJson.License.Type))); + parameters.Add(string.Concat("--iteration ", configJson.Release.Package_Revision)); + parameters.Add(string.Concat("--url ", "\"", EscapeArg(configJson.Homepage), "\"")); + parameters.Add("--verbose"); + + // Map all the payload directories as they need to install on the system + if (configJson.Install_Root != null) parameters.Add(string.Concat(Path.Combine(InputDir, "package_root/="), configJson.Install_Root)); // Package Files + if (configJson.Install_Man != null) parameters.Add(string.Concat(Path.Combine(InputDir, "docs", "host/="), configJson.Install_Man)); // Man Pages + if (configJson.Install_Doc != null) parameters.Add(string.Concat(Path.Combine(InputDir, "templates", "copyright="), configJson.Install_Doc)); // CopyRight File + + return string.Join(" ", parameters); + } + + private string EscapeArg(string arg) + { + var sb = new StringBuilder(); + + bool quoted = ShouldSurroundWithQuotes(arg); + if (quoted) sb.Append("\""); + + for (int i = 0; i < arg.Length; ++i) + { + var backslashCount = 0; + + // Consume All Backslashes + while (i < arg.Length && arg[i] == '\\') + { + backslashCount++; + i++; + } + + // Escape any backslashes at the end of the arg + // This ensures the outside quote is interpreted as + // an argument delimiter + if (i == arg.Length) + { + sb.Append('\\', 2 * backslashCount); + } + + // Escape any preceding backslashes and the quote + else if (arg[i] == '"') + { + sb.Append('\\', (2 * backslashCount) + 1); + sb.Append('"'); + } + + // Output any consumed backslashes and the character + else + { + sb.Append('\\', backslashCount); + sb.Append(arg[i]); + } + } + + if (quoted) sb.Append("\""); + + return sb.ToString(); + } + private bool ShouldSurroundWithQuotes(string argument) + { + // Don't quote already quoted strings + if (argument.StartsWith("\"", StringComparison.Ordinal) && + argument.EndsWith("\"", StringComparison.Ordinal)) + { + return false; + } + + // Only quote if whitespace exists in the string + if (argument.Contains(" ") || argument.Contains("\t") || argument.Contains("\n")) + { + return true; + } + return false; + } + + /// + /// Model classes for reading and storing the JSON. + /// + private class ConfigJson + { + public string Maintainer_Name { get; set; } + public string Maintainer_Email { get; set; } + public string Vendor { get; set; } + public string Package_Name { get; set; } + public string Install_Root { get; set; } + public string Install_Doc { get; set; } + public string Install_Man { get; set; } + public string Short_Description { get; set; } + public string Long_Description { get; set; } + public string Homepage { get; set; } + public string CopyRight { get; set; } + public Release Release { get; set; } + public Control Control { get; set; } + public License License { get; set; } + public JContainer Rpm_Dependencies { get; set; } + public List Package_Conflicts { get; set; } + public List Directories { get; set; } + public string After_Install_Source { get; set; } + public string After_Remove_Source { get; set; } + } + + private class Release + { + public string Package_Version { get; set; } + public string Package_Revision { get; set; } + public string Urgency { get; set; } + public string Changelog_Message { get; set; } + } + + private class Control + { + public string Priority { get; set; } + public string Section { get; set; } + public string Architecture { get; set; } + } + + private class License + { + public string Type { get; set; } + public string Full_Text { get; set; } + } + + private class RpmDependency + { + public string Package_Name { get; set; } + public string Package_Version { get; set; } + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs new file mode 100644 index 00000000000..61e15002906 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs @@ -0,0 +1,227 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using Microsoft.DotNet.Build.Tasks; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + public class CreateFrameworkListFile : BuildTask + { + /// + /// Files to extract basic information from and include in the list. + /// + [Required] + public ITaskItem[] Files { get; set; } + + /// + /// A list of assembly names with classification info such as Profile. A + /// Profile="%(Profile)" attribute is included in the framework list for the matching Files + /// item if %(Profile) contains text. + /// + /// If *any* FileClassifications are passed: + /// + /// *Every* file that ends up listed in the framework list must have a matching + /// FileClassification. + /// + /// Additionally, every FileClassification must find exactly one File. + /// + /// This task fails if the conditions aren't met. This ensures the classification doesn't + /// become out of date when the list of files changes. + /// + /// %(Identity): Assembly name (including ".dll"). + /// %(Profile): List of profiles that apply, semicolon-delimited. + /// %(ReferencedByDefault): Empty (default) or "true"/"false". Indicates whether this file + /// should be referenced by default when the SDK uses this framework. + /// + public ITaskItem[] FileClassifications { get; set; } + + [Required] + public string TargetFile { get; set; } + + public string[] TargetFilePrefixes { get; set; } + + public string[] SingleFileHostIncludeFilenames { 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); + + Dictionary fileClassLookup = FileClassifications + ?.ToDictionary( + item => item.ItemSpec, + item => item, + StringComparer.OrdinalIgnoreCase); + + var singleFileHostIncludeFilenames = SingleFileHostIncludeFilenames?.ToHashSet(); + + var usedFileClasses = new HashSet(); + + foreach (var f in Files + .Where(IsTargetPathIncluded) + .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("IsNative") == "true", + IsSymbolFile = item.GetMetadata("IsSymbolFile") == "true", + IsResourceFile = item.ItemSpec + .EndsWith(".resources.dll", StringComparison.OrdinalIgnoreCase) + }) + .Where(f => + !f.IsSymbolFile && + (f.Filename.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || f.IsNative)) + // Remove duplicate files this task is given. + .GroupBy(f => f.Item.ItemSpec) + .Select(g => g.First()) + // Make order stable between builds. + .OrderBy(f => f.TargetPath, StringComparer.Ordinal) + .ThenBy(f => f.Filename, StringComparer.Ordinal)) + { + string type = "Managed"; + + if (f.IsNative) + { + type = "Native"; + } + else if (f.IsResourceFile) + { + type = "Resources"; + } + + string path = Path.Combine(f.TargetPath, f.Filename).Replace('\\', '/'); + + if (path.StartsWith("runtimes/")) + { + var pathParts = path.Split('/'); + if (pathParts.Length > 1 && pathParts[1].Contains("_")) + { + // This file is a runtime file with a "rid" containing "_". This is assumed + // to mean it's a cross-targeting tool and shouldn't be deployed in a + // self-contained app. Leave it off the list. + continue; + } + } + + var element = new XElement( + "File", + new XAttribute("Type", type), + new XAttribute("Path", path)); + + if (f.IsResourceFile) + { + element.Add( + new XAttribute("Culture", Path.GetFileName(Path.GetDirectoryName(path)))); + } + + 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)); + + if (fileClassLookup != null) + { + if (fileClassLookup.TryGetValue(f.Filename, out ITaskItem classItem)) + { + string profile = classItem.GetMetadata("Profile"); + + if (!string.IsNullOrEmpty(profile)) + { + element.Add(new XAttribute("Profile", profile)); + } + + string referencedByDefault = classItem.GetMetadata("ReferencedByDefault"); + + if (!string.IsNullOrEmpty(referencedByDefault)) + { + element.Add(new XAttribute("ReferencedByDefault", referencedByDefault)); + } + + usedFileClasses.Add(f.Filename); + } + else + { + Log.LogError($"File matches no classification: {f.Filename}"); + } + } + + if (f.IsNative) + { + // presence of inclusion list indicates that + // all other native files should be marked as "DropFromSingleFile" + if (singleFileHostIncludeFilenames != null && + !singleFileHostIncludeFilenames.Contains(f.Filename)) + { + element.Add(new XAttribute("DropFromSingleFile", "true")); + } + } + + frameworkManifest.Add(element); + } + + foreach (var unused in fileClassLookup + ?.Keys.Except(usedFileClasses).OrderBy(p => p) + ?? Enumerable.Empty()) + { + Log.LogError($"Classification matches no files: {unused}"); + } + + Directory.CreateDirectory(Path.GetDirectoryName(TargetFile)); + File.WriteAllText(TargetFile, frameworkManifest.ToString()); + + return !Log.HasLoggedErrors; + } + + private bool IsTargetPathIncluded(ITaskItem item) + { + return TargetFilePrefixes + ?.Any(prefix => item.GetMetadata("TargetPath")?.StartsWith(prefix) == true) ?? true; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs new file mode 100644 index 00000000000..05267536a24 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs @@ -0,0 +1,246 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Linq; +using System.Xml.XPath; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk.src +{ + public class CreateLightCommandPackageDrop : BuildTask + { + private const int _fieldsArtifactId = 0; + private const int _fieldsArtifactPath1 = 6; + private const int _fieldsArtifactPath2 = 1; + + [Required] + public string LightCommandWorkingDir { get; set; } + public bool NoLogo { get; set; } + public bool Fv { get; set; } + public string PdbOut { get; set; } + public string Cultures { get; set; } + public string WixProjectFile { get; set; } + public string ContentsFile { get; set; } + public string OutputsFile { get; set; } + public string BuiltOutputsFile { get; set; } + public ITaskItem [] Loc { get; set; } + public ITaskItem [] Sice { get; set; } + [Required] + public string Out { get; set; } + public ITaskItem [] WixExtensions { get; set; } + [Required] + public ITaskItem [] WixSrcFiles { get; set; } + + [Output] + public string LightCommandPackageNameOutput { get; set; } + // The light command that was originally used to generate the MSI. This is purely used for informational purposes + // and to validate that the light command being created by this task is correct (assist with debugging). + public string OriginalLightCommand { get; set; } + + public override bool Execute() + { + LightCommandPackageNameOutput = Path.GetFileNameWithoutExtension(Out); + string packageDropOutputFolder = Path.Combine(LightCommandWorkingDir, LightCommandPackageNameOutput); + + if (!Directory.Exists(packageDropOutputFolder)) + { + Directory.CreateDirectory(packageDropOutputFolder); + } + XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); + nsmgr.AddNamespace("wix", "http://schemas.microsoft.com/wix/2006/objects"); + + foreach (var wixobj in WixSrcFiles) + { + // copy the file to outputPath + string newWixObjFile = Path.Combine(packageDropOutputFolder, Path.GetFileName(wixobj.ItemSpec)); + Log.LogMessage(LogImportance.Normal, $"Creating modified wixobj file '{newWixObjFile}'..."); + File.Copy(wixobj.ItemSpec, newWixObjFile, true); + + XDocument doc = XDocument.Load(newWixObjFile); + if (doc == null) + { + Log.LogError($"Failed to open the wixobj file '{newWixObjFile}'"); + continue; + } + + // process fragment - WixFile elements + // path in field 7 + string xpath = "//wix:wixObject/wix:section[@type='fragment']/wix:table[@name='WixFile']/wix:row"; + ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath1); + + // process product - WixFile elements + // path in field 7 + xpath = "//wix:wixObject/wix:section[@type='product']/wix:table[@name='WixFile']/wix:row"; + ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath1); + + // process fragment - Binary elements + // path in field 2 + xpath = "//wix:wixObject/wix:section[@type='fragment']/wix:table[@name='Binary']/wix:row"; + ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath2); + + // process product - Icon elements + // path in field 2 + xpath = "//wix:wixObject/wix:section[@type='product']/wix:table[@name='Icon']/wix:row"; + ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath2); + + // process product - WixVariable elements + // path in field 2 + xpath = "//wix:wixObject/wix:section[@type='product']/wix:table[@name='WixVariable']/wix:row"; + ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath2); + + doc.Save(newWixObjFile); + } + if (Loc != null) + { + foreach (var locItem in Loc) + { + var destinationPath = Path.Combine(packageDropOutputFolder, Path.GetFileName(locItem.ItemSpec)); + File.Copy(locItem.ItemSpec, destinationPath, true); + } + } + + // Write Light command to file + string commandFilename = Path.Combine(packageDropOutputFolder, "light.cmd"); + string commandString = string.Empty; + if(OriginalLightCommand != null) + { + commandString += "REM Original light command" + Environment.NewLine; + commandString += "REM " + OriginalLightCommand + Environment.NewLine; + } + commandString += "REM Modified light command" + Environment.NewLine; + commandString += "light.exe"; + commandString += $" -out {Path.GetFileName(Out)}"; + if (NoLogo) + { + commandString += " -nologo"; + } + if (Cultures != null) + { + commandString += $" -culture:{Cultures}"; + } + if (Loc != null) + { + foreach (var locItem in Loc) + { + commandString += $" -loc:{Path.GetFileName(locItem.ItemSpec)}"; + } + } + if(Fv) + { + commandString += " -fv"; + } + if(PdbOut != null) + { + commandString += $" -pdbout {PdbOut}"; + } + if(WixProjectFile != null) + { + var destinationPath = Path.Combine(packageDropOutputFolder, Path.GetFileName(WixProjectFile)); + File.Copy(WixProjectFile, destinationPath, true); + commandString += $" -wixprojectfile {Path.GetFileName(WixProjectFile)}"; + } + if(ContentsFile != null) + { + commandString += $" -contentsfile {Path.GetFileName(ContentsFile)}"; + } + if (OutputsFile != null) + { + commandString += $" -outputsfile {Path.GetFileName(OutputsFile)}"; + } + if (BuiltOutputsFile != null) + { + commandString += $" -builtoutputsfile {Path.GetFileName(BuiltOutputsFile)}"; + } + if (Sice != null) + { + foreach (var siceItem in Sice) + { + commandString += $" -sice:{siceItem.ItemSpec}"; + } + } + if(WixExtensions != null) + { + foreach(var wixExtension in WixExtensions) + { + commandString += $" -ext {wixExtension.ItemSpec}"; + } + } + if(WixSrcFiles != null) + { + foreach(var wixSrcFile in WixSrcFiles) + { + commandString += $" {Path.GetFileName(wixSrcFile.ItemSpec)}"; + } + } + File.WriteAllText(commandFilename, commandString); + + return !Log.HasLoggedErrors; + } + void ProcessXPath(XDocument doc, string xpath, string outputPath, XmlNamespaceManager nsmgr, int pathField1, int pathField2 = 0) + { + IEnumerable iels = doc.XPathSelectElements(xpath, nsmgr); + if (iels != null && iels.Count() > 0) + { + + foreach (XElement row in iels) + { + IEnumerable fields = row.XPathSelectElements("wix:field", nsmgr); + if (fields == null || fields.Count() == 0) + { + Log.LogError($"No fields in row ('{xpath}') of document '{doc.BaseUri}'"); + continue; + } + + int count = 0; + string id = ""; + string oldPath = ""; + string newRelativePath = ""; + bool foundArtifact = false; + + foreach (XElement field in fields) + { + if (count == _fieldsArtifactId) + { + id = field.Value; + } + else if (count == pathField1) + { + oldPath = field.Value; + if (!File.Exists(oldPath)) + { + break; + } + + foundArtifact = true; + newRelativePath = Path.Combine(id, Path.GetFileName(oldPath)); + field.Value = newRelativePath; + } + else if (pathField2 != 0 && count == pathField2) + { + field.Value = newRelativePath; + break; + } + count++; + } + + if (foundArtifact) + { + string newFolder = Path.Combine(outputPath, id); + if (!Directory.Exists(newFolder)) + { + Directory.CreateDirectory(newFolder); + } + + File.Copy(oldPath, Path.Combine(outputPath, newRelativePath), true); + } + } + } + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/ExecWithRetries.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/ExecWithRetries.cs new file mode 100644 index 00000000000..5aeb1d3bd37 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/ExecWithRetries.cs @@ -0,0 +1,116 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Initially copied from https://github.com/dotnet/buildtools/blob/6736870b84e06b75e7df32bb84d442db1b2afa10/src/Microsoft.DotNet.Build.Tasks/ExecWithRetries.cs + +using Microsoft.Build.Framework; +using Microsoft.Build.Tasks; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +{ + /// + /// Run a command and retry if the exit code is not 0. + /// + public class ExecWithRetries : BuildTask, ICancelableTask + { + [Required] + public string Command { get; set; } + + public string WorkingDirectory { get; set; } + + public bool IgnoreStandardErrorWarningFormat { get; set; } + + public int MaxAttempts { get; set; } = 5; + + /// + /// Base, in seconds, raised to the power of the number of retries so far. + /// + public double RetryDelayBase { get; set; } = 6; + + /// + /// A constant, in seconds, added to (base^retries) to find the delay before retrying. + /// + /// The default is -1 to make the first retry instant, because ((base^0)-1) == 0. + /// + public double RetryDelayConstant { get; set; } = -1; + + /// + /// MSBuild message importance to use when logging stdout messages from the command. Default + /// is "High". + /// + public string StandardOutputImportance { get; set; } + + /// + /// MSBuild message importance to use when logging stderr messages from the command. Default + /// is "High". + /// + public string StandardErrorImportance { get; set; } + + private CancellationTokenSource _cancelTokenSource = new CancellationTokenSource(); + + private Exec _runningExec; + + public void Cancel() + { + _runningExec?.Cancel(); + _cancelTokenSource.Cancel(); + } + + public override bool Execute() + { + for (int i = 0; i < MaxAttempts; i++) + { + _runningExec = new Exec + { + BuildEngine = BuildEngine, + Command = Command, + WorkingDirectory = WorkingDirectory, + IgnoreStandardErrorWarningFormat = IgnoreStandardErrorWarningFormat, + StandardOutputImportance = StandardOutputImportance, + StandardErrorImportance = StandardErrorImportance, + LogStandardErrorAsError = false, + IgnoreExitCode = true + }; + + if (!_runningExec.Execute()) + { + Log.LogError("Child Exec task failed to execute."); + break; + } + + int exitCode = _runningExec.ExitCode; + if (exitCode == 0) + { + return true; + } + + string message = $"Exec FAILED: exit code {exitCode} (attempt {i + 1}/{MaxAttempts})"; + + if (i + 1 == MaxAttempts || _cancelTokenSource.IsCancellationRequested) + { + Log.LogError(message); + break; + } + + TimeSpan delay = TimeSpan.FromSeconds( + Math.Pow(RetryDelayBase, i) + RetryDelayConstant); + + Log.LogMessage(LogImportance.High, $"{message} -- Retrying after {delay}..."); + + try + { + Task.Delay(delay, _cancelTokenSource.Token).Wait(); + } + catch (AggregateException e) when (e.InnerException is TaskCanceledException) + { + break; + } + } + return false; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs new file mode 100644 index 00000000000..035c2ba2348 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + internal static partial class FileUtilities + { + private static readonly HashSet s_assemblyExtensions = new HashSet( + new[] { ".dll", ".exe" }, + StringComparer.OrdinalIgnoreCase); + + public static Version GetFileVersion(string sourcePath) + { + var fvi = FileVersionInfo.GetVersionInfo(sourcePath); + + if (fvi != null) + { + return new Version(fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart); + } + + return null; + } + + public static AssemblyName GetAssemblyName(string path) + { + if (!s_assemblyExtensions.Contains(Path.GetExtension(path))) + { + return null; + } + + try + { + return AssemblyName.GetAssemblyName(path); + } + catch (BadImageFormatException) + { + // Not a valid assembly. + return null; + } + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateCurrentVersion.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateCurrentVersion.cs new file mode 100644 index 00000000000..281b2be1130 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateCurrentVersion.cs @@ -0,0 +1,148 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using System; +using System.Globalization; +using System.Text.RegularExpressions; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +{ + public sealed class GenerateCurrentVersion : BuildTask + { + /// + /// The passed in date that will be used to generate a version. (yyyy-MM-dd format) + /// + [Required] + public string SeedDate { get; set; } + + /// + /// Optional parameter containing the Official Build Id. We'll use this to get the revision number out and use it as BuildNumberMinor. + /// + public string OfficialBuildId { get; set; } + + /// + /// Optional parameter that sets the Padding for the version number. Must be 5 or bigger. + /// + public int Padding { get; set; } + + /// + /// If basing off of internal builds version format is not required, this optional parameter lets you pass in a comparison date. + /// + public string ComparisonDate { get; set; } + + /// + /// The Major Version that will be produced given a SeedDate. + /// + [Output] + public string GeneratedVersion { get; set; } + + /// + /// The Revision number that will be produced from the BuildNumber. + /// + [Output] + public string GeneratedRevision { get; set; } + + private const string DateFormat = "yyyy-MM-dd"; + private const string LastModifiedTimeDateFormat = "yyyy-MM-dd HH:mm:ss.FFFFFFF"; + private readonly CultureInfo enUS = new CultureInfo("en-US"); + + public override bool Execute() + { + // If OfficialBuildId is passed in, then use that to calculate the version and revision. + if (string.IsNullOrEmpty(OfficialBuildId)) + { + GeneratedRevision = "0"; + } + else + { + bool success = SetVersionAndRevisionFromBuildId(OfficialBuildId); + return success; + } + + // Calculating GeneratedVersion + if (Padding == 0) + { + Padding = 5; + } + else if (Padding < 5) + { + Log.LogWarning("The specified Padding '{0}' has to be equal to or greater than 5. Using 5 as a default now.", Padding); + Padding = 5; + } + DateTime date; + GeneratedVersion = string.Empty; + if (!(DateTime.TryParseExact(SeedDate, DateFormat, enUS, DateTimeStyles.AssumeLocal, out date))) + { + // Check if the timestamp matches the LastModifiedTimeDateFormat + if (!(DateTime.TryParseExact(SeedDate, LastModifiedTimeDateFormat, enUS, DateTimeStyles.AssumeLocal, out date))) + { + Log.LogError("The seed date '{0}' is not valid. Please specify a date in the short format.({1})", SeedDate, DateFormat); + return false; + } + } + //Convert Date to UTC to converge + date = date.ToUniversalTime(); + GeneratedVersion = GetCurrentVersionForDate(date, ComparisonDate); + if (string.IsNullOrEmpty(GeneratedVersion)) + { + Log.LogError("The date '{0}' is not valid. Please pass in a date after {1}.", SeedDate, ComparisonDate); + return false; + } + return true; + } + + public bool SetVersionAndRevisionFromBuildId(string buildId) + { + Regex regex = new Regex(@"(\d{8})[\-\.](\d+)$"); + string dateFormat = "yyyyMMdd"; + Match match = regex.Match(buildId); + if (match.Success && match.Groups.Count > 2) + { + DateTime buildIdDate; + if (!DateTime.TryParseExact(match.Groups[1].Value, dateFormat, enUS, DateTimeStyles.AssumeLocal, out buildIdDate)) + { + Log.LogError("The OfficialBuildId doesn't follow the expected({0}.rr) format: '{1}'", dateFormat, match.Groups[1].Value); + return false; + } + buildIdDate = buildIdDate.ToUniversalTime(); + GeneratedVersion = GetCurrentVersionForDate(buildIdDate, ComparisonDate); + GeneratedRevision = match.Groups[2].Value; + return true; + } + Log.LogError("Error: Invalid OfficialBuildId was passed: '{0}'", buildId); + return false; + } + + public string GetCurrentVersionForDate(DateTime seedDate, string comparisonDate) + { + DateTime compareDate; + if (string.IsNullOrEmpty(comparisonDate)) + { + /* + * We need to ensure that our build numbers are higher that what we used to ship internal builds so this date + * will make that possible. + */ + compareDate = new DateTime(1996, 4, 1, 0, 0, 0, DateTimeKind.Utc); + } + else + { + bool isValidDate = DateTime.TryParseExact(comparisonDate, DateFormat, enUS, DateTimeStyles.AssumeLocal, out compareDate); + if (!isValidDate) + { + Log.LogError("The comparison date '{0}' is not valid. Please specify a date in the short format.({1})", comparisonDate, DateFormat); + } + //Convert to UTC to converge + compareDate = compareDate.ToUniversalTime(); + } + int months = (seedDate.Year - compareDate.Year) * 12 + seedDate.Month - compareDate.Month; + if (months > 0) //only allow dates after comparedate + { + return string.Format("{0}{1}", months.ToString("D" + (Padding - 2)), seedDate.Day.ToString("D2")); + } + return string.Empty; + } + + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateGuidFromName.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateGuidFromName.cs new file mode 100644 index 00000000000..45b991ac5d5 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateGuidFromName.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using System; +using System.Security.Cryptography; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +{ + public class GenerateGuidFromName : BuildTask + { + [Required] + public string Name { get; set; } + + [Output] + public string GeneratedGuid { get; set; } + + // Generate a Version 5 (SHA1 Name Based) Guid from a name. + public override bool Execute() + { + // Any fixed GUID will do for a namespace. + Guid namespaceId = new Guid("28F1468D-672B-489A-8E0C-7C5B3030630C"); + + using (SHA1 hasher = SHA1.Create()) + { + var nameBytes = System.Text.Encoding.UTF8.GetBytes(Name ?? string.Empty); + var namespaceBytes = namespaceId.ToByteArray(); + + SwapGuidByteOrder(namespaceBytes); + + var streamToHash = new byte[namespaceBytes.Length + nameBytes.Length]; + + Array.Copy(namespaceBytes, streamToHash, namespaceBytes.Length); + Array.Copy(nameBytes, 0, streamToHash, namespaceBytes.Length, nameBytes.Length); + + var hashResult = hasher.ComputeHash(streamToHash); + + var res = new byte[16]; + + Array.Copy(hashResult, res, res.Length); + + unchecked { res[6] = (byte)(0x50 | (res[6] & 0x0F)); } + unchecked { res[8] = (byte)(0x40 | (res[8] & 0x3F)); } + + SwapGuidByteOrder(res); + + GeneratedGuid = (new Guid(res)).ToString(); + } + + return true; + } + + // Do a byte order swap, .NET GUIDs store multi byte components in little + // endian. + private static void SwapGuidByteOrder(byte[] b) + { + Swap(b, 0, 3); + Swap(b, 1, 2); + Swap(b, 5, 6); + Swap(b, 7, 8); + } + + private static void Swap(byte[] b, int x, int y) + { + byte t = b[x]; + b[x] = b[y]; + b[y] = t; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateJsonObjectString.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateJsonObjectString.cs new file mode 100644 index 00000000000..2b3f8403630 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateJsonObjectString.cs @@ -0,0 +1,145 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using System; +using System.IO; +using System.Linq; +using System.Text; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +{ + public class GenerateJsonObjectString : BuildTask + { + private static readonly string __indent1 = new string(' ', 4); + private static readonly string __indent2 = new string(' ', 8); + + /// + /// Properties to include. If multiple properties have the same name, each property value is + /// included in an array. Only specify one value metadata: the first value is used. + /// + /// %(Identity): Name of the property. + /// %(String): String value of the property. This task adds quotes around it in the JSON. + /// %(Object): Object value of the property. Create this with a nested call to this task. + /// + [Required] + public ITaskItem[] Properties { get; set; } + + /// + /// If set, also write the output JSON string to this file. + /// + public string TargetFile { get; set; } + + [Output] + public string Json { get; set; } + + public override bool Execute() + { + var result = new StringBuilder(); + result.AppendLine("{"); + + bool firstProperty = true; + + foreach (var group in Properties.GroupBy(item => item.ItemSpec)) + { + if (firstProperty) + { + firstProperty = false; + } + else + { + result.AppendLine(","); + } + + result.Append(__indent1); + result.Append("\""); + result.Append(group.Key); + result.Append("\": "); + + if (group.Count() == 1) + { + ITaskItem item = group.First(); + WriteProperty(result, item, __indent1); + } + else + { + result.AppendLine("["); + + bool firstArrayLine = true; + + foreach (ITaskItem item in group) + { + if (firstArrayLine) + { + firstArrayLine = false; + } + else + { + result.AppendLine(","); + } + + result.Append(__indent2); + WriteProperty(result, item, __indent2); + } + + result.AppendLine(); + result.Append(__indent1); + result.Append("]"); + } + } + + result.AppendLine(); + result.AppendLine("}"); + + Json = result.ToString(); + + if (!string.IsNullOrEmpty(TargetFile)) + { + Directory.CreateDirectory(Path.GetDirectoryName(TargetFile)); + File.WriteAllText(TargetFile, Json); + } + + return !Log.HasLoggedErrors; + } + + private void WriteProperty(StringBuilder result, ITaskItem item, string indent) + { + string stringValue = item.GetMetadata("String"); + string objectValue = item.GetMetadata("Object"); + + if (!string.IsNullOrEmpty(stringValue)) + { + result.Append("\""); + result.Append(stringValue); + result.Append("\""); + } + else if (!string.IsNullOrEmpty(objectValue)) + { + bool firstObjectLine = true; + + foreach (var line in objectValue.Split( + new[] {Environment.NewLine}, + StringSplitOptions.RemoveEmptyEntries)) + { + if (firstObjectLine) + { + firstObjectLine = false; + } + else + { + result.AppendLine(); + result.Append(indent); + } + + result.Append(line); + } + } + else + { + Log.LogError($"Item '{item.ItemSpec}' has no String or Object value."); + result.Append("null"); + } + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMacOSDistributionFile.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMacOSDistributionFile.cs new file mode 100644 index 00000000000..701e3df339b --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMacOSDistributionFile.cs @@ -0,0 +1,72 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.DotNet.Build.Tasks; +using Microsoft.Extensions.DependencyModel; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Linq; + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + public class GenerateMacOSDistributionFile : BuildTask + { + [Required] + public string TemplatePath { get; set; } + + [Required] + public string ProductBrandName { get; set; } + + [Required] + public string TargetArchitecture { get; set; } + + [Required] + public ITaskItem[] BundledPackages { get; set; } + + [Required] + public string DestinationFile { get; set; } + + public override bool Execute() + { + try + { + XDocument document = XDocument.Load(TemplatePath); + + var titleElement = new XElement("title", $"{ProductBrandName} ({TargetArchitecture})"); + + var choiceLineElements = BundledPackages.Select(component => new XElement("line", new XAttribute("choice", component.GetMetadata("FileNameWithExtension")))); + + var choiceElements = BundledPackages + .Select(component => new XElement("choice", + new XAttribute("id", component.GetMetadata("FileNameWithExtension")), + new XAttribute("visible", "true"), + new XAttribute("title", component.GetMetadata("Title")), + new XAttribute("description", component.GetMetadata("Description")), + new XElement("pkg-ref", new XAttribute("id", component.GetMetadata("FileNameWithExtension"))))); + + var pkgRefElements = BundledPackages + .Select(component => new XElement("pkg-ref", + new XAttribute("id", component.GetMetadata("FileNameWithExtension")), + component.GetMetadata("FileNameWithExtension"))); + + document.Root.Add(new XElement("choices-outline", choiceLineElements)); + document.Root.Add(choiceElements); + document.Root.Add(pkgRefElements); + using XmlWriter writer = XmlWriter.Create(File.OpenWrite(DestinationFile)); + document.WriteTo(writer); + } + catch (Exception ex) + { + Log.LogErrorFromException(ex, false); + return false; + } + return true; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMsiVersion.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMsiVersion.cs new file mode 100644 index 00000000000..54d8ae4435b --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMsiVersion.cs @@ -0,0 +1,102 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +{ + // MSI versioning + // Encode the CLI version to fit into the MSI versioning scheme - https://msdn.microsoft.com/en-us/library/windows/desktop/aa370859(v=vs.85).aspx + // MSI versions are 3 part + // major.minor.build + // Size(bits) of each part 8 8 16 + // So we have 32 bits to encode the CLI version + + // For a CLI version based on commit count: + // Starting with most significant bit this how the CLI version is going to be encoded as MSI Version + // CLI major -> 6 bits + // CLI minor -> 6 bits + // CLI patch -> 6 bits + // CLI commitcount -> 14 bits + // + // For a CLI version based on BuildTools versioning + // CLI major -> 5 bits + // CLI minor -> 5 bits + // CLI patch -> 4 bits + // BuildNumber major -> 14 bits + // BuildNumber minor -> 4 bits + public class GenerateMsiVersion : BuildTask + { + [Required] + public string Major { get; set; } + [Required] + public string Minor { get; set; } + [Required] + public string Patch { get; set; } + public string BuildNumber { get; set; } + public string BuildNumberMajor { get; set; } + public string BuildNumberMinor { get; set; } + [Output] + public string MsiVersion { get; set; } + + public override bool Execute() + { + if(BuildNumber == null && BuildNumberMajor == null) + { + Log.LogError("Either BuildNumber or BuildNumberMajor and BuildNumberMinor are required parameters."); + return false; + } + if(BuildNumber != null && BuildNumberMajor != null) + { + Log.LogError("You must specify either BuildNumber or BuildNumberMajor and BuildNumberMinor, you cannot specify both parameters."); + return false; + } + if (BuildNumberMajor != null && BuildNumberMinor == null) + { + Log.LogError("If you specify a BuildNumberMajor, you must also specify the BuildNumberMinor."); + return false; + } + if(BuildNumber != null) + { + ParseBuildNumber(); + } + else + { + ParseBuildNumberMajorMinor(); + } + return true; + } + private void ParseBuildNumber() + { + var major = int.Parse(Major) << 26; + var minor = int.Parse(Minor) << 20; + var patch = int.Parse(Patch) << 14; + var msiVersionNumber = major | minor | patch | int.Parse(BuildNumber); + + var msiMajor = (msiVersionNumber >> 24) & 0xFF; + var msiMinor = (msiVersionNumber >> 16) & 0xFF; + var msiBuild = msiVersionNumber & 0xFFFF; + + MsiVersion = $"{msiMajor}.{msiMinor}.{msiBuild}"; + } + private void ParseBuildNumberMajorMinor() + { + var major = int.Parse(Major) << 27; + var minor = int.Parse(Minor) << 22; + var patch = int.Parse(Patch) << 18; + + var buildNumberMajor = int.Parse(BuildNumberMajor) & 0x3FFF << 4; + var buildNumberMinor = int.Parse(BuildNumberMinor) & 0xF; + + var msiVersionNumber = major | minor | patch | buildNumberMajor | buildNumberMinor; + + var msiMajor = (msiVersionNumber >> 24) & 0xFF; + var msiMinor = (msiVersionNumber >> 16) & 0xFF; + var msiBuild = msiVersionNumber & 0xFFFF; + + MsiVersion = $"{msiMajor}.{msiMinor}.{msiBuild}"; + } + + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromFileList.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromFileList.cs new file mode 100644 index 00000000000..cef7ec65e66 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromFileList.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.DotNet.Build.Tasks; +using Microsoft.Extensions.DependencyModel; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + public class GeneratePlatformManifestEntriesFromFileList : BuildTask + { + [Required] + public ITaskItem[] Files { get; set; } + + [Output] + public ITaskItem[] PlatformManifestEntries { get; set; } + + public override bool Execute() + { + var entries = new List(); + foreach (var file in Files) + { + entries.Add(new PlatformManifestEntry + { + Name = file.ItemSpec, + AssemblyVersion = FileUtilities.GetAssemblyName(file.GetMetadata("OriginalFilePath"))?.Version.ToString() ?? string.Empty, + FileVersion = FileUtilities.GetAssemblyName(file.GetMetadata("OriginalFilePath"))?.Version.ToString() ?? string.Empty + }); + } + + PlatformManifestEntries = entries.Select(entry => + { + var item = new TaskItem(entry.Name); + item.SetMetadata("AssemblyVersion", entry.AssemblyVersion); + item.SetMetadata("FileVersion", entry.FileVersion); + return item; + }).ToArray(); + return true; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromTemplate.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromTemplate.cs new file mode 100644 index 00000000000..e7ef610602c --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GeneratePlatformManifestEntriesFromTemplate.cs @@ -0,0 +1,101 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.DotNet.Build.Tasks; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + public class GeneratePlatformManifestEntriesFromTemplate : BuildTask + { + [Required] + public ITaskItem[] PlatformManifestEntryTemplates { get; set; } + + [Required] + public ITaskItem[] Files { get; set; } + + public string FallbackAssemblyVersion { get; set; } + + public string FallbackFileVersion { get; set; } + + [Output] + public ITaskItem[] PlatformManifestEntries { get; set; } + + public override bool Execute() + { + List entries = new List(); + var files = Files.ToDictionary(file => Path.GetFileName(file.ItemSpec)); + foreach (var entryTemplate in PlatformManifestEntryTemplates) + { + if (files.TryGetValue(entryTemplate.ItemSpec, out ITaskItem existingFile)) + { + // This file in the platform manifest template exists on this platform. + // Use the information from the file itself in its entry. + entries.Add(new PlatformManifestEntry + { + Name = entryTemplate.ItemSpec, + AssemblyVersion = FileUtilities.GetAssemblyName(existingFile.ItemSpec)?.Version.ToString() ?? string.Empty, + FileVersion = FileUtilities.GetAssemblyName(existingFile.ItemSpec)?.Version.ToString() ?? string.Empty + }); + } + else + { + // This file does not exist on this platform. It only exists on another platform. + var isNativeEntry = entryTemplate.GetMetadata("IsNative") == "true"; + var entryTemplateExtension = Path.GetExtension(entryTemplate.ItemSpec); + // Use file version 0.0.0.0 for non-Windows executable and shared library files + bool useFileVersionZero = isNativeEntry && entryTemplateExtension != ".dll" && entryTemplateExtension != ".exe"; + string assemblyVersion = string.Empty; + string fileVersion = string.Empty; + if (isNativeEntry) + { + assemblyVersion = "0.0.0.0"; + } + else + { + string localAssemblyVersionFallback = entryTemplate.GetMetadata("FallbackAssemblyVersion"); + assemblyVersion = !string.IsNullOrEmpty(localAssemblyVersionFallback) ? localAssemblyVersionFallback : FallbackAssemblyVersion; + } + if (useFileVersionZero) + { + fileVersion = "0.0.0.0"; + } + else + { + string localFileVersionFallback = entryTemplate.GetMetadata("FallbackFileVersion"); + fileVersion = !string.IsNullOrEmpty(localFileVersionFallback) ? localFileVersionFallback : FallbackFileVersion; + } + entries.Add(new PlatformManifestEntry + { + Name = entryTemplate.ItemSpec, + AssemblyVersion = assemblyVersion, + FileVersion = fileVersion + }); + } + } + + PlatformManifestEntries = entries.Select(entry => + { + var item = new TaskItem(entry.Name); + if (string.IsNullOrEmpty(entry.AssemblyVersion)) + { + Log.LogError($"The platform manifest entry for '{entry.Name}' does not have a fallback assembly version specified and is not built on this platform."); + } + item.SetMetadata("AssemblyVersion", entry.AssemblyVersion); + if (string.IsNullOrEmpty(entry.FileVersion)) + { + Log.LogError($"The platform manifest entry for '{entry.Name}' does not have a fallback file version specified and is not built on this platform."); + } + item.SetMetadata("FileVersion", entry.FileVersion); + return item; + }).ToArray(); + return !Log.HasLoggedErrors; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs new file mode 100644 index 00000000000..e3f07fb74ec --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs @@ -0,0 +1,112 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.DotNet.Build.Tasks; +using Microsoft.Extensions.DependencyModel; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + public class GenerateSharedFrameworkDepsFile : BuildTask + { + [Required] + public string TargetFrameworkMoniker { get; set; } + + [Required] + public string RuntimeIdentifier { get; set; } + + [Required] + public string SharedFrameworkName { get; set; } + + [Required] + public string SharedFrameworkPackName { get; set; } + + [Required] + public string Version { get; set; } + + [Required] + public ITaskItem[] Files { get; set; } + + [Required] + public string IntermediateOutputPath { get; set; } + + [Output] + public ITaskItem GeneratedDepsFile { get; set; } + + public override bool Execute() + { + var target = new TargetInfo(TargetFrameworkMoniker, RuntimeIdentifier, string.Empty, isPortable: false); + var runtimeFiles = new List(); + var nativeFiles = new List(); + var resourceAssemblies = new List(); + + foreach (var file in Files) + { + var filePath = file.ItemSpec; + var fileName = Path.GetFileName(filePath); + var fileVersion = FileUtilities.GetFileVersion(filePath)?.ToString() ?? string.Empty; + var assemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version; + string cultureMaybe = file.GetMetadata("Culture"); + if (!string.IsNullOrEmpty(cultureMaybe)) + { + resourceAssemblies.Add(new ResourceAssembly(Path.Combine(cultureMaybe, fileName), cultureMaybe)); + } + else if (assemblyVersion == null) + { + var nativeFile = new RuntimeFile(fileName, null, fileVersion); + nativeFiles.Add(nativeFile); + } + else + { + var runtimeFile = new RuntimeFile(fileName, + fileVersion: fileVersion, + assemblyVersion: assemblyVersion.ToString()); + runtimeFiles.Add(runtimeFile); + } + } + + var runtimeLibrary = new RuntimeLibrary("package", + SharedFrameworkPackName, + Version, + hash: string.Empty, + runtimeAssemblyGroups: new[] { new RuntimeAssetGroup(string.Empty, runtimeFiles) }, + nativeLibraryGroups: new[] { new RuntimeAssetGroup(string.Empty, nativeFiles) }, + resourceAssemblies, + Array.Empty(), + hashPath: null, + path: $"{SharedFrameworkPackName.ToLowerInvariant()}/{Version}", + serviceable: true); + + var context = new DependencyContext(target, + CompilationOptions.Default, + Enumerable.Empty(), + new[] { runtimeLibrary }, + Enumerable.Empty()); + + var depsFilePath = Path.Combine(IntermediateOutputPath, $"{SharedFrameworkName}.deps.json"); + try + { + using var depsStream = File.Create(depsFilePath); + new DependencyContextWriter().Write(context, depsStream); + GeneratedDepsFile = new TaskItem(depsFilePath); + } + catch (Exception ex) + { + // If there is a problem, ensure we don't write a partially complete version to disk. + if (File.Exists(depsFilePath)) + { + File.Delete(depsFilePath); + } + Log.LogErrorFromException(ex, false); + return false; + } + return true; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/PlatformManifestEntry.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/PlatformManifestEntry.cs new file mode 100644 index 00000000000..55843662e73 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/PlatformManifestEntry.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + struct PlatformManifestEntry + { + public string Name { get; set; } + public string AssemblyVersion { get; set; } + public string FileVersion { get; set; } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/StabilizeWixFileId.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/StabilizeWixFileId.cs new file mode 100644 index 00000000000..61d516d4b5a --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/StabilizeWixFileId.cs @@ -0,0 +1,106 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using System; +using System.Linq; +using System.Xml.Linq; + +namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +{ + /// + /// In a WiX source file, replaces the Id of a File with some given string in order to stabilize + /// it. This allows external tooling such as signature validators to rely on a stable identifier + /// for certain files. + /// + public class StabilizeWixFileId : BuildTask + { + /// + /// File to read from. This is expected to be an output from heat.exe. + /// + /// Expected format: + /// + /// + /// + /// + /// + /// + /// + /// ... + /// + [Required] + public string SourceFile { get; set; } + + /// + /// File to write to. May be the same as SourceFile. + /// + [Required] + public string OutputFile { get; set; } + + /// + /// Set of files to stabilize. This matches the end of the "Source" attribute in the WiX + /// source file. If exactly one match isn't found in the WiX source file, this task fails. + /// + /// %(Identity): The file source to replace. + /// %(ReplacementId): The replacement for Id that won't change per-build. + /// + [Required] + public ITaskItem[] FileElementToStabilize { get; set; } + + public override bool Execute() + { + XDocument content = XDocument.Load(SourceFile); + + XNamespace rootNamespace = content.Root.GetDefaultNamespace(); + XName GetQualifiedName(string name) => rootNamespace.GetName(name); + + foreach (var file in FileElementToStabilize) + { + string replacement = file.GetMetadata("ReplacementId"); + + if (string.IsNullOrEmpty(replacement)) + { + Log.LogError($"{nameof(FileElementToStabilize)} {file.ItemSpec} has null/empty ReplacementId metadata."); + continue; + } + + XElement[] matchingFileElements = content.Element(GetQualifiedName("Wix")) + .Elements(GetQualifiedName("Fragment")) + .SelectMany(f => f.Elements(GetQualifiedName("ComponentGroup"))) + .SelectMany(cg => cg.Elements(GetQualifiedName("Component"))) + .SelectMany(c => c.Elements(GetQualifiedName("File"))) + .Where(f => f.Attribute("Source")?.Value + ?.EndsWith(file.ItemSpec, StringComparison.OrdinalIgnoreCase) == true) + .ToArray(); + + if (matchingFileElements.Length != 1) + { + Log.LogError( + $"Expected 1 match for '{file.ItemSpec}', found {matchingFileElements.Length}: " + + string.Join(", ", matchingFileElements.Select(e => e.ToString()))); + + continue; + } + + XAttribute nameAttribute = matchingFileElements[0].Attribute("Id"); + + if (nameAttribute is null) + { + Log.LogError($"Match has no Id attribute: {matchingFileElements[0]}"); + continue; + } + + Log.LogMessage( + $"Setting '{file.ItemSpec}' Id to '{replacement}' for File with Source " + + matchingFileElements[0].Attribute("Source").Value); + + nameAttribute.Value = replacement; + } + + content.Save(OutputFile); + + return !Log.HasLoggedErrors; + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.MultiRid.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.MultiRid.targets new file mode 100644 index 00000000000..64ba4c0acc8 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.MultiRid.targets @@ -0,0 +1,92 @@ + + + + + + + + <_RuntimeIdentifiers Include="$(RuntimeIdentifiers)" /> + + <_RuntimeIdentifiers Include="@(_RuntimeIdentifiers->Trim()->Distinct())" /> + <_InnerBuildProjects Include="$(MSBuildProjectFile)"> + RuntimeIdentifier=%(_RuntimeIdentifiers.Identity) + + + + + + + + + + + + + + + Build + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props new file mode 100644 index 00000000000..3a44b5e9f41 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props @@ -0,0 +1,4 @@ + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets new file mode 100644 index 00000000000..411a57492d8 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + %(CurrentProjectServicingConfiguration.PatchVersion) + $(MostRecentProducedServicingPatchVersion) + + + + + + + true + + + + <_TargetRuntimeIdentifiers Include="$(RuntimeIdentifiers)" /> + <_TargetInstallerRuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> + + + + + <_RidInRidList Condition="'%(_TargetRuntimeIdentifiers.Identity)' == '$(RuntimeIdentifier)'">true + true + + + + <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true + true + + + + + + + + $(SharedFrameworkName).Ref + $(SharedFrameworkName).Ref + pack.targeting + + + $(SharedFrameworkName).Runtime.$(RuntimeIdentifier) + $(SharedFrameworkName).Runtime + sharedframework.$(SharedFrameworkName) + + + $(SharedFrameworkName).Host.$(RuntimeIdentifier) + $(SharedFrameworkName).Host + pack.apphost + + + $(SharedFrameworkName) + $(PackageId) + pack.$(PlatformPackageType.ToLower()) + + + + + <_PackageTypeRequiresRid Condition="'$(PlatformPackageType)' == 'RuntimePack' or '$(PlatformPackageType)' == 'AppHostPack'">true + + + + + + + + + $(BuildDependsOn);_GetSkipBuildProps + <_GlobalPropertiesToRemoveForPublish> + GenerateCrossArchMsi; + GenerateMSI; + GeneratePkg; + GenerateDeb; + GenerateRpm; + IsShipping; + ComponentMsiFile; + InstallerRuntimeIdentifier; + InstallerTargetArchitecture; + CrossArchContentsArch + + + + + <_GlobalPropertiesToRemoveForPublish Include="$(_GlobalPropertiesToRemoveForPublish)" /> + + + + + + + + $(InstallerRuntimeIdentifier.Substring(0, $(InstallerRuntimeIdentifier.LastIndexOf('-')))) + $(InstallerRuntimeIdentifier.Substring($(InstallerRuntimeIdentifier.LastIndexOf('-'))).TrimStart('-')) + $(TargetArchitecture) + + + + + + <_osSupportsWixBasedInstallers Condition="$([MSBuild]::IsOsPlatform(Windows)) and '$(TargetRuntimeOS)' == 'win'">true + + <_osArchSupportsWixBasedInstallers>$(_osSupportsWixBasedInstallers) + <_osArchSupportsWixBasedInstallers Condition="'$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'arm64'">false + + + + + + true + true + true + + + + + + + + $(PreReleaseVersionLabel.Substring(0,1).ToUpperInvariant()) + $(ReleaseBrandSuffix)$(PreReleaseVersionLabel.Substring(1)) + $(ReleaseBrandSuffix) $(PreReleaseVersionIteration) + + + + + + + + $(VersionPrefix) + $(VersionPrefix) $(ReleaseBrandSuffix) + + $(ProductBrandPrefix) Targeting Pack - $(ProductBrandSuffix) + $(ProductBrandPrefix) Runtime - $(ProductBrandSuffix) + $(ProductBrandPrefix) AppHost Pack - $(ProductBrandSuffix) + $(ProductBrandPrefix) $(BundleNameSuffix) - $(ProductBrandSuffix) + $(ProductBrandPrefix) $(PackageBrandNameSuffix) - $(ProductBrandSuffix) + + + + + $(RuntimeIdentifier) + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.props new file mode 100644 index 00000000000..24643491660 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.props @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.targets new file mode 100644 index 00000000000..61c77afaf9e --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.targets @@ -0,0 +1,14 @@ + + + + + + + + true + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj new file mode 100644 index 00000000000..adbe84df1f8 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-wix/acquire-wix.proj b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-wix/acquire-wix.proj new file mode 100644 index 00000000000..48f58f1bc71 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-wix/acquire-wix.proj @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/bundle.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/bundle.targets new file mode 100644 index 00000000000..c7806c2f15c --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/bundle.targets @@ -0,0 +1,164 @@ + + + + + + true + true + + + + + + + + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GenerateExeBundle" + Properties="GenerateExeBundle=true" + Condition="'$(GenerateExeBundle)' == 'true'" /> + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GeneratePkgBundle" + Properties="GeneratePkgBundle=true" + Condition="'$(GeneratePkgBundle)' == 'true'" /> + + + + + + + + + + + $(SharedFrameworkArchiveName) + + + + + + $(SharedFrameworkInstallerName)-$(MajorVersion).$(MinorVersion) + $(VersionedInstallerName.ToLowerInvariant()) + 1 + $(VersionPrefix) + + + + .exe + .pkg + + + + <_InstallerIntermediatesDir>$(IntermediateOutputPath)$(InstallerName)/$(InstallerPackageVersion)/ + + $(Version)-$(TargetRuntimeOS)-$(InstallerTargetArchitecture) + + + $(SharedFrameworkInstallerName)-$(InstallerBuildPart) + <_InstallerFile Condition="'$(_InstallerFile)' == ''">$(PackageOutputPath)$(InstallerFileNameWithoutExtension)$(InstallerExtension) + $(PackageOutputPath)$(InstallerFileNameWithoutExtension)-engine.exe + + + + + + + CreateWixInstaller + GenerateMSI=true + GenerateExeBundle + + + + + CreatePkg + GeneratePkg=true + GeneratePkgBundle + + + + + + + + + + + + + + + + + + + + + + <_MacOSIntermediatesPath>$(IntermediateOutputPath)macos/ + <_MacOSDistributionFile>$(_MacOSIntermediatesPath)distribution-file.xml + + + + + + + + <_MacOSPackagesToBundle> + %(FileName)%(Extension) + + + + + + + <_pkgArgs> + <_pkgArgs Condition="'$(MacOSBundleResourcesPath)' == ''">$(_pkgArgs) --resources $(MacOSBundleResourcesPath) + <_pkgArgs>$(_pkgArgs) --identifier $(MacOSBundleIdentifierName) + <_pkgArgs>$(_pkgArgs) --version $(ProductVersion) + <_pkgArgs>$(_pkgArgs) --package-path $(_MacOSIntermediatesPath) + <_pkgArgs>$(_pkgArgs) --distribution $(_MacOSDistributionFile) + <_pkgArgs>$(_pkgArgs) $(_InstallerFile) + + + + + + + + + + $(BuildDependsOn);GenerateBundles + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/compat b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/compat new file mode 100644 index 00000000000..ec635144f60 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/source/format b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/source/format new file mode 100644 index 00000000000..163aaf8d82b --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_tool.sh b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_tool.sh new file mode 100644 index 00000000000..9e069b7a1e0 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_tool.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +## Load Functions ## +source $SCRIPT_DIR/scripts/debian_build_lib.sh + +## Debian Package Creation Functions ## +execute(){ + if ! parse_args_and_set_env_vars "$@"; then + exit 1 + fi + + # Exit if required validation fails + if ! validate_inputs; then + exit 1 + fi + + parse_config_and_set_env_vars + clean_or_create_build_dirs + package_all + generate_all + create_source_tarball + + # Actually Build Package Files + (cd ${PACKAGE_SOURCE_DIR}; debuild -us -uc) +} + +parse_args_and_set_env_vars(){ + OPTIND=1 # Reset in case getopts has been used previously in the shell. + + while getopts ":n:v:i:o:h" opt; do + case $opt in + n) + export PACKAGE_NAME="$OPTARG" + ;; + v) + export PACKAGE_VERSION="$OPTARG" + ;; + i) + export INPUT_DIR="$OPTARG" + ;; + o) + export OUTPUT_DIR="$OPTARG" + ;; + h) + print_help + return 1 + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + return 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + return 1 + ;; + esac + done + + # Special Input Directories + Paths + ABSOLUTE_PLACEMENT_DIR="${INPUT_DIR}/\$" + PACKAGE_ROOT_PLACEMENT_DIR="${INPUT_DIR}/package_root" + CONFIG="$INPUT_DIR/debian_config.json" + + return 0 +} + +print_help(){ + echo "Usage: package_tool [-i ] [-o ] + [-n ] [-v ] [-h] + + REQUIRED: + -i : Input directory conforming to package_tool conventions and debian_config.json + -o : Output directory for debian package and other artifacts + + OPTIONAL: + -n : name of created package, will override value in debian_config.json + -v : version of created package, will override value in debian_config.json + -h: Show this message + + NOTES: + See Readme for more information on package_tool conventions and debian_config.json format + https://github.com/dotnet/cli/tree/master/packaging/debian/package_tool + " +} + +validate_inputs(){ + local ret=0 + if [[ -z "$INPUT_DIR" ]]; then + echo "ERROR: -i Not Specified" + ret=1 + fi + + if [[ -z "$OUTPUT_DIR" ]]; then + echo "ERROR: -o Not Specified." + ret=1 + fi + + if [[ ! -d "$PACKAGE_ROOT_PLACEMENT_DIR" ]]; then + echo "ERROR: package_root directory does not exist" + echo $PACKAGE_ROOT_PLACEMENT_DIR + ret=1 + fi + + if [[ ! -f "$CONFIG" ]]; then + echo "ERROR: debian_config.json file does not exist" + echo $CONFIG + ret=1 + fi + + return $ret +} + +parse_config_and_set_env_vars(){ + extract_base_cmd="python $SCRIPT_DIR/scripts/extract_json_value.py" + + # Arguments Take Precedence over Config + [ -z "$PACKAGE_VERSION" ] && PACKAGE_VERSION="$($extract_base_cmd $CONFIG "release.package_version")" + [ -z "$PACKAGE_NAME" ] && PACKAGE_NAME="$($extract_base_cmd $CONFIG "package_name")" + + # Inputs + INPUT_SAMPLES_DIR="$INPUT_DIR/samples" + INPUT_DOCS_DIR="$INPUT_DIR/docs" + DOCS_JSON_PATH="$INPUT_DIR/docs.json" + + PACKAGE_SOURCE_DIR="${OUTPUT_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}" + + if ! INSTALL_ROOT="$($extract_base_cmd $CONFIG "install_root")"; then + INSTALL_ROOT="/usr/share/$PACKAGE_NAME" + fi + + DEBIAN_DIR="${PACKAGE_SOURCE_DIR}/debian" + DOCS_DIR="${PACKAGE_SOURCE_DIR}/docs" +} + +clean_or_create_build_dirs(){ + rm -rf ${PACKAGE_SOURCE_DIR} + mkdir -p $DEBIAN_DIR +} + +package_all(){ + package_static_files + package_package_root_placement + package_absolute_placement + package_samples + package_docs + package_install_scripts +} + +generate_all(){ + generate_config_templates + generate_manpages + generate_manpage_manifest + generate_sample_manifest + write_debian_install_file +} + +create_source_tarball(){ + rm -f ${OUTPUT_DIR}/${PACKAGE_NAME}_${PACKAGE_VERSION}.orig.tar.gz + tar -cvzf ${OUTPUT_DIR}/${PACKAGE_NAME}_${PACKAGE_VERSION}.orig.tar.gz -C $PACKAGE_SOURCE_DIR . +} + +## Packaging Functions ## +package_static_files(){ + cp -a $SCRIPT_DIR/package_files/debian/* ${PACKAGE_SOURCE_DIR}/debian +} + +package_package_root_placement(){ + add_dir_to_install ${PACKAGE_ROOT_PLACEMENT_DIR} "" +} + +package_absolute_placement(){ + if [[ -d "$ABSOLUTE_PLACEMENT_DIR" ]]; then + abs_in_package_dir="\$" + + add_dir_to_install ${ABSOLUTE_PLACEMENT_DIR} $abs_in_package_dir + + # Get List of all files in directory tree, relative to ABSOLUTE_PLACEMENT_DIR + abs_files=( $(_get_files_in_dir_tree $ABSOLUTE_PLACEMENT_DIR) ) + + # For each file add a a system placement + for abs_file in ${abs_files[@]} + do + parent_dir=$(dirname $abs_file) + filename=$(basename $abs_file) + + add_system_file_placement "$abs_in_package_dir/$abs_file" "/$parent_dir" + done + fi +} + +package_samples(){ + if [[ -d "$INPUT_SAMPLES_DIR" ]]; then + cp -a $INPUT_SAMPLES_DIR/. $PACKAGE_SOURCE_DIR + fi +} + +package_docs(){ + if [[ -d "$INPUT_DOCS_DIR" ]]; then + mkdir -p $DOCS_DIR + cp -a $INPUT_DOCS_DIR/. $DOCS_DIR + fi +} + +package_install_scripts(){ + # copy scripts for the package's control section like preinst, postint, etc + if [[ -d "$INPUT_DIR/debian" ]]; then + cp -a "$INPUT_DIR/debian/." $DEBIAN_DIR + fi +} + +## Generation Functions ## +generate_config_templates(){ + python ${SCRIPT_DIR}/scripts/config_template_generator.py $CONFIG $SCRIPT_DIR/templates/debian $DEBIAN_DIR $PACKAGE_NAME $PACKAGE_VERSION +} + +generate_manpages(){ + if [[ -f "$DOCS_JSON_PATH" ]]; then + mkdir -p $DOCS_DIR + + # Generate the manpages from json spec + python ${SCRIPT_DIR}/scripts/manpage_generator.py ${DOCS_JSON_PATH} ${DOCS_DIR} + fi +} + +generate_manpage_manifest(){ + # Get a list of files generated relative to $DOCS_DIR + generated_manpages=( $(_get_files_in_dir_tree $DOCS_DIR) ) + + # Get path relative to $PACKAGE_SOURCE_DIR to prepend to each filename + # This syntax is bash substring removal + docs_rel_path=${DOCS_DIR#${PACKAGE_SOURCE_DIR}/} + + # Remove any existing manifest + rm -f ${DEBIAN_DIR}/${PACKAGE_NAME}.manpages + + for manpage in ${generated_manpages[@]} + do + echo "${docs_rel_path}/${manpage}" >> "${DEBIAN_DIR}/${PACKAGE_NAME}.manpages" + done +} + +generate_sample_manifest(){ + if [[ -d "$INPUT_SAMPLES_DIR" ]]; then + generated_manpages=( $(_get_files_in_dir_tree $INPUT_SAMPLES_DIR) ) + + rm -f sample_manifest + for sample in ${samples[@]} + do + echo "$sample" >> "${DEBIAN_DIR}/${PACKAGE_NAME}.examples" + done + else + echo "Provide a 'samples' directory in INPUT_DIR to package samples" + fi +} + +execute "$@" diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/config_template_generator.py b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/config_template_generator.py new file mode 100644 index 00000000000..6b8b21c9e12 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/config_template_generator.py @@ -0,0 +1,268 @@ +#!/usr/bin/python +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +# Parses debian_config.json and generates appropriate templates +# Where optional defaults exist, they are defined in the template_dict +# of the appropriate generation function + +import os +import sys +import json +import datetime + +FILE_CHANGELOG = 'changelog' +FILE_CONTROL = 'control' +FILE_COPYRIGHT = 'copyright' +FILE_SYMLINK_FORMAT = '{package_name}.links' +FILE_RULES = 'rules' + +PACKAGE_ROOT_FORMAT = "usr/share/{package_name}" +CHANGELOG_DATE_FORMAT = "%a, %d %b %Y %H:%M:%S %z" + +# UTC Timezone for Changelog date +class UTC(datetime.tzinfo): + def utcoffset(self, dt): + return datetime.timedelta(0) + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return datetime.timedelta(0) + +# Generation Functions +def generate_and_write_all(config_data, template_dir, output_dir, package_name=None, package_version=None): + try: + changelog_contents = generate_changelog( + config_data, + template_dir, + package_name=package_name, + package_version=package_version) + + control_contents = generate_control(config_data, template_dir, package_name=package_name) + copyright_contents = generate_copyright(config_data, template_dir) + symlink_contents = generate_symlinks(config_data, package_name=package_name) + rules_contents = generate_rules(config_data, template_dir) + except Exception as exc: + print exc + help_and_exit("Error: Generation Failed, check your config file.") + + write_file(changelog_contents, output_dir, FILE_CHANGELOG) + write_file(control_contents, output_dir, FILE_CONTROL) + write_file(copyright_contents, output_dir, FILE_COPYRIGHT) + write_file(rules_contents, output_dir, FILE_RULES) + + # Symlink File is optional + if symlink_contents: + symlink_filename = get_symlink_filename(config_data, package_name=package_name) + write_file(symlink_contents, output_dir, symlink_filename) + + return + +def generate_rules(config_data, template_dir): + template = get_template(template_dir, FILE_RULES) + + ignored_dependency_packages = config_data.get("debian_ignored_dependencies", None) + override_text = "" + + if ignored_dependency_packages != None: + override_text = "override_dh_shlibdeps:\n\tdh_shlibdeps --dpkg-shlibdeps-params=\"" + + for package in ignored_dependency_packages: + override_text += "-x{0} ".format(package) + + override_text += "\"" + + return template.format(overrides=override_text) + +def generate_changelog(config_data, template_dir, package_version=None, package_name=None): + template = get_template(template_dir, FILE_CHANGELOG) + + release_data = config_data["release"] + + # Allow for Version Override + config_package_version = release_data["package_version"] + package_version = package_version or config_package_version + + template_dict = dict(\ + PACKAGE_VERSION=package_version, + PACKAGE_REVISION=release_data["package_revision"], + CHANGELOG_MESSAGE=release_data["changelog_message"], + URGENCY=release_data.get("urgency", "low"), + + PACKAGE_NAME=package_name or config_data["package_name"], + MAINTAINER_NAME=config_data["maintainer_name"], + MAINTAINER_EMAIL=config_data["maintainer_email"], + DATE=datetime.datetime.now(UTC()).strftime(CHANGELOG_DATE_FORMAT) + ) + + contents = template.format(**template_dict) + + return contents + +def generate_control(config_data, template_dir, package_name=None): + template = get_template(template_dir, FILE_CONTROL) + + dependency_data = config_data.get("debian_dependencies", None) + dependency_str = get_dependendent_packages_string(dependency_data) + + conflict_data = config_data.get("package_conflicts", []) + conflict_str = ', '.join(conflict_data) + + # Default to empty dict, so we don't explode on nested optional values + control_data = config_data.get("control", dict()) + + template_dict = dict(\ + SHORT_DESCRIPTION=config_data["short_description"], + LONG_DESCRIPTION=config_data["long_description"], + HOMEPAGE=config_data.get("homepage", ""), + + SECTION=control_data.get("section", "misc"), + PRIORITY=control_data.get("priority", "low"), + ARCH=control_data.get("architecture", "all"), + + DEPENDENT_PACKAGES=dependency_str, + CONFLICT_PACKAGES=conflict_str, + + PACKAGE_NAME=package_name or config_data["package_name"], + MAINTAINER_NAME=config_data["maintainer_name"], + MAINTAINER_EMAIL=config_data["maintainer_email"] + ) + + contents = template.format(**template_dict) + + return contents + +def generate_copyright(config_data, template_dir): + template = get_template(template_dir, FILE_COPYRIGHT) + + license_data = config_data["license"] + + template_dict = dict(\ + COPYRIGHT_TEXT=config_data["copyright"], + LICENSE_NAME=license_data["type"], + LICENSE_TEXT=license_data["full_text"] + ) + + contents = template.format(**template_dict) + + return contents + +def generate_symlinks(config_data, package_name=None): + symlink_entries = [] + package_root_path = get_package_root(config_data, package_name=package_name) + + symlink_data = config_data.get("symlinks", dict()) + + for package_rel_path, symlink_path in symlink_data.iteritems(): + + package_abs_path = os.path.join(package_root_path, package_rel_path) + + symlink_entries.append( '%s %s' % (package_abs_path, symlink_path) ) + + return '\n'.join(symlink_entries) + +# Helper Functions +def get_package_root(config_data, package_name=None): + config_install_root = config_data.get("install_root", None) + package_name = package_name or config_data["package_name"] + + return config_install_root or PACKAGE_ROOT_FORMAT.format(package_name=package_name) + +def get_symlink_filename(config_data, package_name=None): + package_name = package_name or config_data["package_name"] + return FILE_SYMLINK_FORMAT.format(package_name=package_name) + +def get_dependendent_packages_string(debian_dependency_data): + if debian_dependency_data is None: + return "" + + dependencies = [] + + for debian_package_name in debian_dependency_data: + dep_str = debian_package_name + + if debian_dependency_data[debian_package_name].get("package_version", None): + debian_package_version = debian_dependency_data[debian_package_name].get("package_version") + + dep_str += " (>= %s)" % debian_package_version + + dependencies.append(dep_str) + + # Leading Comma is important here + return ', ' + ', '.join(dependencies) + + +def load_json(json_path): + json_data = None + with open(json_path, 'r') as json_file: + json_data = json.load(json_file) + + return json_data + +def get_template(template_dir, name): + path = os.path.join(template_dir, name) + template_contents = None + + with open(path, 'r') as template_file: + template_contents = template_file.read() + + return template_contents + +def write_file(contents, output_dir, name): + path = os.path.join(output_dir, name) + + with open(path, 'w') as out_file: + out_file.write(contents) + + return + +# Tool Functions +def help_and_exit(msg): + print msg + sys.exit(1) + +def print_usage(): + print "Usage: config_template_generator.py [config file path] [template directory path] [output directory] (package name) (package version)" + +def parse_and_validate_args(): + if len(sys.argv) < 4: + print_usage() + help_and_exit("Error: Invalid Arguments") + + config_path = sys.argv[1] + template_dir = sys.argv[2] + output_dir = sys.argv[3] + name_override = None + version_override = None + + if len(sys.argv) >= 5: + name_override = sys.argv[4] + + if len(sys.argv) >= 6: + version_override = sys.argv[5] + + if not os.path.isfile(config_path): + help_and_exit("Error: Invalid config file path") + + if not os.path.isdir(template_dir): + help_and_exit("Error: Invalid template directory path") + + if not os.path.isdir(output_dir): + help_and_exit("Error: Invalid output directory path") + + return (config_path, template_dir, output_dir, name_override, version_override) + +def execute(): + config_path, template_dir, output_dir, name_override, version_override = parse_and_validate_args() + + config_data = load_json(config_path) + + generate_and_write_all(config_data, template_dir, output_dir, package_name = name_override, package_version=version_override) + +if __name__ == "__main__": + execute() diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/debian_build_lib.sh b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/debian_build_lib.sh new file mode 100644 index 00000000000..18d388864fd --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/debian_build_lib.sh @@ -0,0 +1,171 @@ +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +# This file is not intended to be executed directly +# Import these functions using source +# +# Relies on these environment variables: +# PACKAGE_SOURCE_DIR :: Package Source Staging Directory +# INSTALL_ROOT :: Absolute path of package installation root + +# write_debian_install_file +# Summary: Writes the contents of the "install_placement" array to the debian/install +# This array is populated by calls to the "add_system_file_placement" function +# Usage: write_debian_install_file +write_debian_install_file(){ + # Remove any existing install file, we need to overwrite it + rm -f ${PACKAGE_SOURCE_DIR}/debian/install + + for i in "${install_placement[@]}" + do + echo "${i}" >> "${PACKAGE_SOURCE_DIR}/debian/install" + done +} + +# add_system_file_placement +# Summary: Registers a file placement on the filesystem from the package by populating the "install_placement" array +# Usage: add_system_file_placement {local path of file in package} {absolute path of directory to place file in} +add_system_file_placement(){ + #Initialize placement_index variable + if [[ -z "$placement_index" ]]; then + placement_index=0 + fi + + install_placement[${placement_index}]="${1} ${2}" + placement_index=$((${placement_index}+1)) +} + +# add_system_dir_placement +# Summary: Registers a directory placement on the post-installation package from an in-package path +add_system_dir_placement(){ + + in_package_dir=$1 + abs_installation_dir=$2 + + dir_files=( $(_get_files_in_dir_tree $PACKAGE_SOURCE_DIR/$in_package_dir) ) + + # If in_package_dir isn't empty include a slash + if [ ! -z "$in_package_dir" ]; then + in_package_dir="${in_package_dir}/" + fi + + for rel_filepath in ${dir_files[@]} + do + local parent_path=$(dirname $rel_filepath) + + # If there is no parent, parent_path = "." + if [[ "$parent_path" == "." ]]; then + add_system_file_placement "${in_package_dir}${rel_filepath}" "${abs_installation_dir}" + else + add_system_file_placement "${in_package_dir}${rel_filepath}" "${abs_installation_dir}/${parent_path}" + fi + + done +} + +# add_file_to_install +# Summary: Adds a file from the local filesystem to the package and installs it rooted at INSTALL_ROOT +# Usage: add_install_file {relative path to local file} {relative path to INSTALL_ROOT to place file} +add_file_to_install(){ + copy_from_file=$1 + rel_install_path=$2 + + local filename=$(basename $copy_from_file) + local parent_dir=$(dirname $copy_from_file) + + # Create Relative Copy From Path + rel_copy_from_file=${copy_from_file#$parent_dir/} + + # Delete any existing file and ensure path exists + rm -f ./${PACKAGE_SOURCE_DIR}/${rel_install_path}/${filename} + mkdir -p ./${PACKAGE_SOURCE_DIR}/${rel_install_path} + + dir_files=( "$rel_copy_from_file" ) + + _copy_files_to_package $parent_dir $rel_install_path "${dir_files[@]}" + + add_system_file_placement "${rel_install_path}/${filename}" "${INSTALL_ROOT}/$rel_install_path" +} + +# add_dir_to_install +# Summary: Adds contents of a directory on the local filesystem to the package and installs them rooted at INSTALL_ROOT +# Note: Does not install the directory passed, only its contents +# Usage: add_dir_to_install {relative path of directory to copy} {relative path to INSTALL_ROOT to place directory tree} +add_dir_to_install(){ + + copy_from_dir=$1 + rel_install_path=$2 + + # Delete and Create any existing directory + mkdir -p ${PACKAGE_SOURCE_DIR}/${rel_install_path} + + dir_files=( $(_get_files_in_dir_tree $copy_from_dir) ) + + _copy_files_to_package "$copy_from_dir" "$rel_install_path" "${dir_files[@]}" + + for file in "${dir_files[@]}" + do + file_rel_dir="$(dirname $file)" + add_system_file_placement "${rel_install_path}/${file}" "${INSTALL_ROOT}/$rel_install_path/${file_rel_dir}" + done +} + +# Usage: _copy_files_to_package {local files root directory} {relative directory in package to copy to} "${filepath_array[@]}" +# Note: The specific syntax on the parameter shows how to pass an array +_copy_files_to_package(){ + local_root_dir=$1 + package_dest_dir=$2 + + # Consume the remaining input as an array + shift; shift; + rel_filepath_list=( $@ ) + + for rel_filepath in ${rel_filepath_list[@]} + do + local parent_dir=$(dirname $rel_filepath) + local filename=$(basename $rel_filepath) + + mkdir -p ${PACKAGE_SOURCE_DIR}/${package_dest_dir}/${parent_dir} + + # Ignore $parent_dir if it there isn't one + if [[ "$parent_dir" == "." ]]; then + cp "${local_root_dir}/${rel_filepath}" "${PACKAGE_SOURCE_DIR}/${package_dest_dir}" + else + cp "${local_root_dir}/${rel_filepath}" "${PACKAGE_SOURCE_DIR}/${package_dest_dir}/${parent_dir}" + fi + + done +} + +# Usage: _get_files_in_dir_tree {path of directory} +_get_files_in_dir_tree(){ + + root_dir=$1 + + # Use Globstar expansion to enumerate all directories and files in the tree + shopt -s globstar + shopt -s dotglob + dir_tree_list=( "${root_dir}/"** ) + + # Build a new array with only the Files contained in $dir_tree_list + local index=0 + for file_path in "${dir_tree_list[@]}" + do + if [ -f $file_path ]; then + dir_tree_file_list[${index}]=$file_path + index=$(($index+1)) + fi + done + + # Remove $root_dir prefix from each path in dir_tree_file_list + # This is confusing syntax, so here's a reference link (Substring Removal) + # http://wiki.bash-hackers.org/syntax/pe + dir_tree_file_list=( "${dir_tree_file_list[@]#${root_dir}/}" ) + + # Echo is the return mechanism + echo "${dir_tree_file_list[@]}" +} + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/extract_json_value.py b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/extract_json_value.py new file mode 100644 index 00000000000..74f26a6ffdd --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/extract_json_value.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +# Extract Json Value +# +# Very simple tool to ease extracting json values from the cmd line. +import os +import sys +import json + +def print_usage(): + print """ + Usage: extract_json_value.py [json file path] [key of value to extract] + For nested keys, use . separator + """ + +def help_and_exit(msg=None): + print msg + print_usage() + sys.exit(1) + +def parse_and_validate_args(): + + if len(sys.argv) < 3: + help_and_exit(msg="Error: Invalid Args") + + json_path = sys.argv[1] + json_key = sys.argv[2] + + if not os.path.isfile(json_path): + help_and_exit("Error: Invalid json file path") + + return json_path, json_key + +def extract_key(json_path, json_key): + json_data = None + + with open(json_path, 'r') as json_file: + json_data = json.load(json_file) + + nested_keys = json_key.split('.') + json_context = json_data + + for key in nested_keys: + json_context = json_context.get(key, None) + + if json_context is None: + help_and_exit("Error: Invalid json key") + + return str(json_context) + +def execute(): + json_path, json_key = parse_and_validate_args() + + value = extract_key(json_path, json_key) + + return value + +if __name__ == "__main__": + print execute() + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/manpage_generator.py b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/manpage_generator.py new file mode 100644 index 00000000000..c62e6807901 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/manpage_generator.py @@ -0,0 +1,304 @@ +#!/usr/bin/python +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +# manpage_generator +# Converts top level docs.json format command info to +# nroff manpage format. Done in python for easy json parsing. +# +# Usage: argv[1] = path to docs.json; argv[2] = output path + +import sys +import os +import json +import datetime + +SECTION_SEPARATOR = "\n.P \n" +MANPAGE_EXTENSION = ".1" + +# For now this is a magic number +# See https://www.debian.org/doc/manuals/maint-guide/dother.en.html#manpage +SECTION_NUMBER = 1 + +def generate_man_pages(doc_path, output_dir): + + with open(doc_path) as doc_file: + doc_json = None + try: + doc_json = json.load(doc_file) + except: + raise Exception("Failed to load json file. Check formatting.") + + tools = doc_json.get("tools", None) + + if tools is None: + raise Exception("No tool sections in doc.json") + + for tool_name in tools: + tool_data = tools[tool_name] + + man_page_content = generate_man_page(tool_name, tool_data) + man_page_path = get_output_path(tool_name, output_dir) + + write_man_page(man_page_path, man_page_content) + +def get_output_path(toolname, output_dir): + out_filename = toolname + MANPAGE_EXTENSION + + return os.path.join(output_dir, out_filename) + +def write_man_page(path, content): + with open(path, 'w') as man_file: + man_file.write(content) + + #Build Fails without a final newline + man_file.write('\n') + +def generate_man_page(tool_name, tool_data): + + sections = [ + generate_header_section(tool_name, tool_data), + generate_name_section(tool_name, tool_data), + generate_synopsis_section(tool_name, tool_data), + generate_description_section(tool_name, tool_data), + generate_options_section(tool_name, tool_data), + generate_author_section(tool_name, tool_data), + generate_copyright_section(tool_name, tool_data) + ] + + return SECTION_SEPARATOR.join(sections) + +def generate_header_section(tool_name, tool_data):# + roff_text_builder = [] + + header_format = ".TH {program_name} {section_number} {center_footer} {left_footer} {center_header}" + + today = datetime.date.today() + today_string = today.strftime("%B %d, %Y") + + format_args = { + "program_name" : tool_name, + "section_number" : SECTION_NUMBER, + "center_footer" : "", # Omitted + "left_footer" : "", # Omitted + "center_header" : "" # Omitted + } + + roff_text_builder.append(header_format.format(**format_args)) + + return SECTION_SEPARATOR.join(roff_text_builder) + +def generate_name_section(tool_name, tool_data):# + roff_text_builder = [] + roff_text_builder.append(".SH NAME") + + tool_short_description = tool_data.get("short_description", "") + name_format = ".B {program_name} - {short_description}" + + name_format_args = { + "program_name": tool_name, + "short_description" : tool_short_description + } + + roff_text_builder.append(name_format.format(**name_format_args)) + + return SECTION_SEPARATOR.join(roff_text_builder) + +def generate_synopsis_section(tool_name, tool_data):# + roff_text_builder = [] + roff_text_builder.append(".SH SYNOPSIS") + + synopsis_format = '.B {program_name} {command_name} \n.RI {options} " "\n.I "{argument_list_name}"' + + tool_commands = tool_data.get("commands", []) + for command_name in tool_commands: + command_data = tool_commands[command_name] + + # Default options to empty list so the loop doesn't blow up + options = command_data.get("options", []) + argument_list = command_data.get("argumentlist", None) + + # Construct Option Strings + option_string_list = [] + argument_list_name = "" + + for option_name in options: + option_data = options[option_name] + + specifier_short = option_data.get("short", None) + specifier_long = option_data.get("long", None) + parameter = option_data.get("parameter", None) + + option_string = _option_string_helper(specifier_short, specifier_long, parameter) + + option_string_list.append(option_string) + + # Populate Argument List Name + if argument_list: + argument_list_name = argument_list.get("name", "") + + cmd_format_args = { + 'program_name' : tool_name, + 'command_name' : command_name, + 'options' : '" "'.join(option_string_list), + 'argument_list_name' : argument_list_name + } + + cmd_string = synopsis_format.format(**cmd_format_args) + + roff_text_builder.append(cmd_string) + + return SECTION_SEPARATOR.join(roff_text_builder) + +def generate_description_section(tool_name, tool_data):# + roff_text_builder = [] + roff_text_builder.append(".SH DESCRIPTION") + + # Tool Description + long_description = tool_data.get("long_description", "") + roff_text_builder.append(".PP {0}".format(long_description)) + + # Command Descriptions + cmd_description_format = ".B {program_name} {command_name}\n{command_description}" + + tool_commands = tool_data.get("commands", []) + for command_name in tool_commands: + command_data = tool_commands[command_name] + + command_description = command_data.get("description", "") + + format_args = { + "program_name" : tool_name, + "command_name" : command_name, + "command_description" : command_description + } + + cmd_string = cmd_description_format.format(**format_args) + + roff_text_builder.append(cmd_string) + + return SECTION_SEPARATOR.join(roff_text_builder) + +def generate_options_section(tool_name, tool_data):# + roff_text_builder = [] + roff_text_builder.append(".SH OPTIONS") + + options_format = '.TP\n.B {option_specifiers}\n{option_description}' + + tool_commands = tool_data.get("commands", []) + for command_name in tool_commands: + command_data = tool_commands[command_name] + + # Default to empty list so the loop doesn't blow up + options = command_data.get("options", []) + + for option_name in options: + option_data = options[option_name] + + specifier_short = option_data.get("short", None) + specifier_long = option_data.get("long", None) + parameter = option_data.get("parameter", None) + description = option_data.get("description", "") + + option_specifiers_string = _option_string_helper(specifier_short, + specifier_long, + parameter, + include_brackets = False, + delimiter=' ", " ') + + format_args = { + "option_specifiers": option_specifiers_string, + "option_description" : description + } + + roff_text_builder.append(options_format.format(**format_args)) + + return SECTION_SEPARATOR.join(roff_text_builder) + +def generate_author_section(tool_name, tool_data):# + roff_text_builder = [] + roff_text_builder.append(".SH AUTHOR") + + author_format = '.B "{author_name}" " " \n.RI ( "{author_email}" )' + + author_name = tool_data.get("author", "") + author_email = tool_data.get("author_email", "") + + format_args = { + "author_name" : author_name, + "author_email" : author_email + } + + roff_text_builder.append(author_format.format(**format_args)) + + return SECTION_SEPARATOR.join(roff_text_builder) + +def generate_copyright_section(tool_name, tool_data):# + roff_text_builder = [] + roff_text_builder.append(".SH COPYRIGHT") + + copyright_data = tool_data.get("copyright") + + roff_text_builder.append('.B "{0}"'.format(copyright_data)) + + return SECTION_SEPARATOR.join(roff_text_builder) + +def _option_string_helper(specifier_short, specifier_long, parameter, include_brackets = True, delimiter = " | "): + option_string = "" + + if include_brackets: + option_string = " [ " + + if specifier_short: + option_string += ' "{0}" '.format(specifier_short) + + if specifier_short and specifier_long: + option_string += delimiter + + if specifier_long: + option_string += ' "{0}" '.format(specifier_long) + + if parameter: + option_string += ' " " ' + option_string += ' "{0}" '.format(parameter) + + if include_brackets: + option_string += " ] " + + return option_string + + +def print_usage(): + print "Usage: argv[1] = path to docs.json; argv[2] = output path" + print "Example: manpage_generator.py ../docs.json ./dotnet-1.0/debian" + +def parse_args(): + doc_path = sys.argv[1] + output_dir = sys.argv[2] + + return (doc_path, output_dir) + +def validate_args(doc_path, output_dir): + if not os.path.isfile(doc_path): + raise Exception("Docs.json path is not valid.") + + if not os.path.isdir(output_dir): + raise Exception("Output Directory Path is not valid.") + +def execute_command_line(): + try: + doc_path, output_dir = parse_args() + + validate_args(doc_path, output_dir) + + generate_man_pages(doc_path, output_dir) + + except Exception as exc: + print "Error: ", exc + print_usage() + +if __name__ == "__main__": + execute_command_line() diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/build_setup.sh b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/build_setup.sh new file mode 100644 index 00000000000..12c223aacbc --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/build_setup.sh @@ -0,0 +1,21 @@ +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +install_dependencies(){ + # Add LLdb 3.6 package source + echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.6 main" | tee /etc/apt/sources.list.d/llvm.list + wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add - + + #Install Deps + apt-get update + apt-get install -y debhelper build-essential devscripts git liblttng-ust-dev lldb-3.6-dev +} + +setup(){ + install_dependencies +} + +setup \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/test_setup.sh b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/test_setup.sh new file mode 100644 index 00000000000..a7cdd95c2b3 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/test_setup.sh @@ -0,0 +1,28 @@ +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +install_dependencies(){ + # Add LLdb 3.6 package source + echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.6 main" | tee /etc/apt/sources.list.d/llvm.list + wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add - + + #Install Deps + apt-get update + apt-get install -y debhelper build-essential devscripts git liblttng-ust-dev lldb-3.6-dev +} + +install_bats(){ + git clone https://github.com/sstephenson/bats.git + cd bats + ./install.sh /usr/local +} + +setup(){ + install_dependencies + install_bats +} + +setup \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/changelog b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/changelog new file mode 100644 index 00000000000..8eccaab397c --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/changelog @@ -0,0 +1,5 @@ +{PACKAGE_NAME} ({PACKAGE_VERSION}-{PACKAGE_REVISION}) unstable; urgency={URGENCY} + + * {CHANGELOG_MESSAGE} + + -- {MAINTAINER_NAME} <{MAINTAINER_EMAIL}> {DATE} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/control b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/control new file mode 100644 index 00000000000..114d8493042 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/control @@ -0,0 +1,20 @@ +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +Source: {PACKAGE_NAME} +Maintainer: {MAINTAINER_NAME} <{MAINTAINER_EMAIL}> +Section: {SECTION} +Priority: {PRIORITY} +Standards-Version: 3.9.2 +Build-Depends: debhelper (>=9) +Homepage: {HOMEPAGE} + +Package: {PACKAGE_NAME} +Architecture: {ARCH} +Depends: {DEPENDENT_PACKAGES} +Conflicts: {CONFLICT_PACKAGES} +Description: {SHORT_DESCRIPTION} + {LONG_DESCRIPTION} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/copyright b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/copyright new file mode 100644 index 00000000000..72febbba8af --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/copyright @@ -0,0 +1,10 @@ +Comment: Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. + +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +Files: * +Copyright: {COPYRIGHT_TEXT} +License: {LICENSE_NAME} + +License: {LICENSE_NAME} + {LICENSE_TEXT} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/rules b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/rules new file mode 100644 index 00000000000..b5cbfb27e20 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/rules @@ -0,0 +1,12 @@ +#!/usr/bin/make -f +# +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# + +{overrides} + +%: + dh $@ + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.multirid.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.multirid.targets new file mode 100644 index 00000000000..59fc23d142f --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.multirid.targets @@ -0,0 +1,31 @@ + + + + <_RuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> + + <_RuntimeIdentifiers Include="@(_RuntimeIdentifiers->Trim()->Distinct())" /> + <_InnerBuildProjects Include="$(MSBuildProjectFile)"> + InstallerRuntimeIdentifier=%(_RuntimeIdentifiers.Identity) + + + + + + + + + + + + + + $(BuildDependsOn);GenerateInstallers + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.props new file mode 100644 index 00000000000..14db6908e8a --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.props @@ -0,0 +1,6 @@ + + + true + true + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets new file mode 100644 index 00000000000..ee8db9200d1 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets @@ -0,0 +1,492 @@ + + + <_InstallerTargetsImported>true + + + + + + true + + true + + true + + + + + $(GenerateInstallers) + $(GenerateInstallers) + false + false + + + + + + + + + + + + + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GenerateDeb" + Properties="GenerateDeb=true" + Condition="'$(GenerateDeb)' == 'true'" /> + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GenerateRpm" + Properties="GenerateRpm=true" + Condition="'$(GenerateRpm)' == 'true'" /> + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GenerateMsi" + Properties="GenerateMSI=true" + Condition="'$(GenerateMSI)' == 'true'" /> + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GenerateCrossArchMsi" + Properties="GenerateCrossArchMsi=true" + Condition="'$(GenerateCrossArchMsi)' == 'true'" /> + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GeneratePkg" + Properties="GeneratePkg=true" + Condition="'$(GeneratePkg)' == 'true'" /> + <_InstallerBuildProject Include="$(MSBuildProjectFile)" + Targets="GenerateVSInsertionNupkg" + Properties="GenerateMSI=$(GenerateMSI);GenerateCrossArchMsi=$(GenerateCrossArchMsi)" + Condition="'$(GenerateVSInsertionPackages)' == 'true'" /> + + + + + + + + + + + + + + $(SharedFrameworkArchiveName) + + + + + + $(SharedFrameworkInstallerName)-$(MajorVersion).$(MinorVersion) + $(SharedFrameworkInstallerName) + $(VersionedInstallerName.ToLowerInvariant()) + 1 + $(VersionPrefix) + + + + + _$(CrossArchContentsArch) + + + + .msi + .pkg + .deb + .rpm + .exe + $(InstallerExtension) + + + + $(VersionPrefix)~$(VersionSuffix) + + + + 0.1.$(VersionSuffix) + $([System.String]::Copy('$(InstallerPackageRelease)').Replace('-', '_')) + + + + <_InstallerIntermediatesDir>$(IntermediateOutputPath)$(InstallerName)/$(InstallerPackageVersion)/ + + $(Version)-$(TargetRuntimeOS)-$(InstallerTargetArchitecture) + $(ProductVersion)-$(InstallerTargetArchitecture) + + + $(SharedFrameworkInstallerName)-$(InstallerBuildPart)$(CrossArchContentsBuildPart) + <_InstallerFile Condition="'$(_InstallerFile)' == ''">$(PackageOutputPath)$(InstallerFileNameWithoutExtension)$(InstallerExtension) + $(PackageOutputPath)$(InstallerFileNameWithoutExtension).exe + $(PackageOutputPath)$(InstallerFileNameWithoutExtension)-engine.exe + + + + + + + + + + + + + <_DebuildPresent>false + <_DebuildPresent Condition=" '$(_DebuildSearchExitCode)' == '0' ">true + + + + + + + + + + + + + + + <_FPMPresent>false + <_FPMPresent Condition=" '$(_FPMSearchExitCode)' == '0' ">true + + + + + + + + + <_ConfigJsonFile>$(_LayoutDirectory)debian_config.json + <_DebIntermediatesDir>$(IntermediateOutputPath)out-deb + + <_DebToolArgs>-i $(_LayoutDirectory) + <_DebToolArgs>$(_DebToolArgs) -o $(_DebIntermediatesDir) + <_DebToolArgs>$(_DebToolArgs) -n $(VersionedInstallerName) + <_DebToolArgs>$(_DebToolArgs) -v $(InstallerPackageVersion) + + + + + + + + + + + <_GeneratedDebFiles Include="$(_DebIntermediatesDir)/*.deb" /> + + + + + + + + + + + + <_DebDependenciesJsonEntry Include="@(LinuxPackageDependency->'"%(Identity)" : { "package_version" : "%(Version)"}')" /> + + + <_DebJsonProperty Include="debian_dependencies" Object="{@(_DebDependenciesJsonEntry, ', ')}" /> + <_DebJsonProperty Include="@(DebJsonProperty)" /> + + + + + + + <_ConfigJsonFile>$(_LayoutDirectory)rpm_config.json + <_RpmIntermediatesDir>$(_InstallerIntermediatesDir)out-rpm + + + <_RpmTemplatesLayoutDir>$(_LayoutDirectory)templates/ + + + + <_RpmTemplateFile Include="$(MSBuildThisFileDirectory)rpm_templates/**/*" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_FpmDependenciesJsonEntry Include="@(LinuxPackageDependency->'{"package_name" : "%(Identity)", "package_version" : "%(Version)"}')" /> + + + <_RpmJsonProperty Include="vendor" String=".NET Foundation" /> + <_RpmJsonProperty Include="install_doc" String="/usr/share/doc/$(VersionedInstallerName)/" /> + <_RpmJsonProperty Include="rpm_dependencies" Object="[@(_FpmDependenciesJsonEntry,', ')]" /> + <_RpmJsonProperty Include="@(RpmJsonProperty)" /> + + + + + + + + + + + + + + + + + + + + + + + <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/ + + + + + <_MacOSVersionComponent Condition="'$(IncludeVersionInMacOSComponentName)' == 'true'">.$(ProductVersion) + <_MacOSComponentName Condition="'$(_MacOSComponentName)' == ''">com.microsoft.dotnet.$(MacOSComponentNamePackType)$(_MacOSVersionComponent).component.osx.x64 + <_MacOSSharedInstallDir>/usr/local/share/dotnet + + <_pkgArgs> + <_pkgArgs>$(_pkgArgs) --root $(_SharedFrameworkOutputPathRoot) + <_pkgArgs>$(_pkgArgs) --identifier $(_MacOSComponentName) + <_pkgArgs>$(_pkgArgs) --version $(ProductVersion) + <_pkgArgs>$(_pkgArgs) --install-location $(_MacOSSharedInstallDir) + <_pkgArgs Condition="'$(MacOSScriptsDirectory)' != ''">$(_pkgArgs) --scripts $(MacOSScriptsDirectory) + <_pkgArgs>$(_pkgArgs) $(_InstallerFile) + + + + + + + <_CreatedPkg Include="$(_InstallerFile)" Description="$(MacOSPackageDescription)" Title="$(ProductBrandName) ($(TargetArchitecture))" /> + + + + + + + <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/ + + + + + + <_LayoutDirectory>$(IntermediateOutputPath)installer/layoutDirectory/ + <_LayoutPackageRoot>$(_LayoutDirectory)package_root + <_LayoutAbsolute>$(_LayoutDirectory)$ + <_LayoutSamples>$(_LayoutDirectory)samples + <_LayoutDocs>$(_LayoutDirectory)docs + + + + + + + + + + + + + + + <_LayoutFiles Include="$(_SharedFrameworkOutputPathRoot)/**/*" /> + + + + + + + + + + + + + $([System.IO.File]::ReadAllText('$(LicenseFile)').Replace('%0A', '\n').Replace('"', '\"')) + + + + <_LinuxPackageReleaseProperty Include="package_version" String="1.0.0.0" /> + <_LinuxPackageReleaseProperty Include="package_revision" String="$(InstallerPackageRelease)" /> + <_LinuxPackageReleaseProperty Include="urgency" String="low" /> + <_LinuxPackageReleaseProperty Include="changelog_message" String="https://github.com/dotnet/core/tree/master/release-notes" /> + + <_LinuxPackageControlProperty Include="priority" String="standard" /> + <_LinuxPackageControlProperty Include="section" String="libs" /> + <_LinuxPackageControlProperty Include="architecture" String="amd64" /> + + <_LinuxPackageLicenseProperty Include="type" String="MIT and ASL 2.0 and BSD" /> + <_LinuxPackageLicenseProperty Include="full_text" String="$(FullLicenseText)" /> + + + + + + + + + + + + + + <_CommonLinuxPackageProperty Include="package_name" String="$(VersionedInstallerName)" /> + <_CommonLinuxPackageProperty Include="short_description" String="$(MSBuildProjectName) $(InstallerPackageVersion)" /> + <_CommonLinuxPackageProperty Include="maintainer_name" String=".NET Team" /> + <_CommonLinuxPackageProperty Include="maintainer_email" String="dotnetpackages@dotnetfoundation.org" /> + <_CommonLinuxPackageProperty Include="install_root" String="/usr/share/dotnet" /> + <_CommonLinuxPackageProperty Include="long_description" String=".NET is a development platform that you can use to build command-line applications, microservices and modern websites. 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 (https://github.com/dotnet/core). We happily accept issues and PRs." /> + <_CommonLinuxPackageProperty Include="homepage" String="https://github.com/dotnet/core" /> + <_CommonLinuxPackageProperty Include="copyright" String="2017 Microsoft" /> + <_CommonLinuxPackageProperty Include="release" Object="$(_JsonReleaseObject)" /> + <_CommonLinuxPackageProperty Include="control" Object="$(_JsonControlObject)" /> + <_CommonLinuxPackageProperty Include="license" Object="$(_JsonLicenseObject)" /> + + + + + $(BuildDependsOn);GenerateInstallers + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/resources/dotnetbackground.png b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/resources/dotnetbackground.png new file mode 100644 index 0000000000000000000000000000000000000000..16a6bf22ba789a0eb41ce25b92ba9915b2293af3 GIT binary patch literal 4601 zcmeHKc~FyC693Rq6b4v^Lq{OE<7ga0R0au`z^EJw!>wH54wn!Jhuk4iDdoNtaJWY@ z2*?q_k;n~$NfZbXxeQ1m1Vlit1Ok`@HdFJ@RBhGP)=q8J*3`bL*RQ%?zh8HC_j}bZ z#m34^O5%hB002_guNm6`zyTxxh?O5XERwjC6{1CpScIL~6`+1dc~QiC;eXlkG5`>= zBn4iFMEudvYt9h>Al>)d6r-Z5d;mb^LFAV;qU zN*W*R4GVqdeW<$RUb4#lsIz0^vXTMf@ap_j6ZF@5Dv-f|>d|~F74bR;zIZ`3*3+V; zd1NuY>d+Otez?R@ycF_bCqK@^U}5!eew)R^l@QLrDz^v4D=mtk8!UwQaS9?8(KT%%v7&ihY{8yrk_p5^nuO+2rPK)|kw>ZriMY zmNTmKvMaYE>1%j@>T1)mxiwkf!Y$h`;GiHO1nkXS1~)?c)u3s_OXDEybI605`KsHr zU`_7MWE9UyQO8-!S3wKysm@zjrr)c*glM)b+jqi2vs!Wz*@Wn|{vl3LMlzJat92Rq zi5dVgu6~=$-*3md<18D*dVY10?}cfA!d4G$?YyTt7!%$+K4hh@mX}P8BF)nADw(Er zpo%vH)KYJ+1A3L^NTp0DH2thbMQkU44fk^9H7>o=WS6!tau?#MnI;wO$}(7P@AEC| z!`?p4+7#2ml9kr=#?s@eMP*q{Kbd$D4CK3;I~8jtXe_+@@8(%vL8K|$)x{JAC98}s zEhTSqTgI?vg9b*h03)|!5&mB~E=0LDj|EWrx0Vsk#M;ulW$!V{Sjoo%+U71dQYSy> zJobI=-D-pAl>m~O3bw(C z;cq=QL(yYK10$x6jt0(APl2~X=d-eIS8?-p;ls5Phx9&`eTW;SzV{0c?Hg+rFU(DoyIcM97nD8Kb0VC z_lmPAL4~$;QS_K=o8k-I`=xv~WS?`p*>87f>UKrAK5um~ErDM9>I2jmXPc}#&GSa; zoKCC#FnAtRH_k3B!m1IGQ*R4EUn{56rv=>_;Z=s*(jH`M#ji2%_$|T1)0)_LhVoa3 z?%Z!Vk{BF2N(IkW_5$0N5nvpXXZ^%DNFtFUO zgLHcj1Cl|*Af>6@vTbq`E8&~?T#~V)YuwhdH(z&4eKpeqo@-84&zxign9yz0&F9A+ zfBCA?zi@5+Wna+eVVc0kKYBZ;n}w#H02y=t z;wtrxUc4=k0^a}9aBaJx1wrnQLeKDo8*^9bz9S4jB78&cSg8^U19u#yWG&0Wfjg@G z-$)UYuRKw4OMtNRWjeDhwYXqC`aTm{#J*q2?F<0`aFU4)K@M|blrdEfadY)Hb(2$=2`vp(pywGs})xNoU?np9@H)O zHvsq$I4lmw>}CwlBXDKKvB`lr~+$n&jcn;ui zI#ksrcehom;7%ps&%#qJj6$t$Z}Chq(Utc@KeVEfx4Wf55MJGLj+XnGian?cwr zUG?R!A^A1a2LOx7hewF6xH7OP2<2HHxBD>^zL($RuKL&m z8`iO$buI-G@>4o#b{JxazTB~4iR1DO z8j+0i23%nb=WdDUk{~}7CtTvMU)^{~+BS=fiCy>{1^^?_R!>NtL`ml@Z1jK)Op6&? zUqjMAx4YFce7t68`N^;wE9TLQ;=q5ivjO_EjSkTvGR2;@XYwG^_X`;7{ zV`^CDbP(`s{5BElxEM(7YoDNi>#;tZlqg8tM5*G0ko-Vry*&H?@P^=%2qmF?^}9N7 zkTcSTCz9wVgp4$83Y^6;($I4$EUrGw1n$TMT^AMCk#Nso#}59zl&Y*xW$DC0al_cy zTnoA3Kn28R&$R_zk)E$eul`16Rfgq@ZYD1jc5}c~-vRY8mDSyPe8p6&$ep7q3xwW- z?w(jg4|hLT@7g5q#mwC$2nvw7vjPu>yuWa+v1&~8iU3x%bBRzRM3Z}vNhdSYA;_!V zHlIaQ>lRQ-w6UjLwq`yRMBU!1%dFXJ&@W`u{YJ{A0G+Uh(nR!{1B>H=)a?Yrgx6Xl zY#F8qukv7L6r^jbPII>2+NjXd_wINI+1jJS09F!a4l^Ka590e^8sq(@`jo8j!HLr* zz#Z}_hG!5=LgT^(d2L~&#vX6AZleHS3|eciHd1pVc*ajU;DgDc9@{wKyoyoVm?36*`M_dW1i2S?MTbKgqaD>`?!WrfdTJtK9nM+q(r&icGexzTN^~G z$vh2r-K?h(LJ+!XtwZXP-oomNoq^@jeo%%brZ>2rWbo1(#ozU(NR_=iffZEK!q_YD zOdUh?)UB|M)7F$1JEJ0Rf$v`(hPRJpGV=zS%tjmu$H{_xK=Y$(4h|i|M0ZsuQLEZ3 z6{w^(xj#UeO}xv6!_+%8f9WF?jlHtpVn|!NuB9U)X=cY=oQk2S{Q!z>IyhL zCz^Xi6}J$fLYs6_)_MI1y6};=G=DeB6AKN*CFw2i&T?Cj!gpEnfMU_1-AbXT3;Zx| z;fFxD5muT@HlBJ+gAijg&;89brIlS}-Q4i*=!GiZ8c>jUX^QUvrF^*d1(&aF25HbiF}HEvKuHKWte@kcro}Ee1~aQ;s?PTh7EJ`mBe4o=q@yQQb&Rem~wA16#1Gp6@UiSR*W4!-r zz&PsfM__=HlO#uG1$|g)Q4R?-G&~eaD*?cxFO+~EX8&sBPyY-4bAa{KEWn6#7^WMJ!IS7;87YDrUQLbq=&_AAS+k>(~=O>*=&z{4SfF5S<=N?`S zeBz9mY{8E&=y=HLkFWF2>D&t2ivxgo_)?N_1d}sls1bGLOzCHf_)FY?FuR_hd9ZlL zhY=q=FP{b^U#CcTLtipXzj!}xWtNY^Lqv_&g>NMQw;GE*+{&jO)3&2X;C0Iztc<8W zWWWt#z%Ru;hk@+y10ud(v - {PACKAGE_VERSION}-{PACKAGE_REVISION} +- {CHANGELOG_MESSAGE} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/copyright b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/copyright new file mode 100644 index 00000000000..ba561b5eceb --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/copyright @@ -0,0 +1,8 @@ +Comment: Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. + +Files: * +Copyright: {COPYRIGHT_TEXT} +License: {LICENSE_NAME} + +License: {LICENSE_NAME} + {LICENSE_TEXT} \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props new file mode 100644 index 00000000000..a55ad906beb --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props @@ -0,0 +1,18 @@ + + + $(RepoRoot)LICENSE.TXT + + ResolveFrameworkReferences; + ResolveReferences; + + true + false + true + true + true + $(NoWarn);NU5128;NU5131 + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets new file mode 100644 index 00000000000..3850c7c3337 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -0,0 +1,526 @@ + + + $([System.IO.Path]::GetFileName('$(LicenseFile)')) + true + true + true + $(AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder);.map + + + + + + <_SymbolFilesToPackage> + true + + + + + + <_SymbolFilesToPackage Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(FileName).pdb')" Exclude="@(RuntimePackAsset)" /> + <_SymbolFilesToPackage Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(FileName)%(Extension).dbg')" Exclude="@(RuntimePackAsset)" /> + <_SymbolFilesToPackage Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(FileName)%(Extension).dwarf')" Exclude="@(RuntimePackAsset)" /> + <_SymbolFilesToPackage Remove="@(_SymbolFilesToPackage)" Condition="!Exists('%(Identity)')" /> + + + + + + + + + + + + + + + + <_r2rSymbolFiles Include="@(ResolvedFileToPublish->'%(RootDir)%(Directory)%(FileName).ni.pdb')" /> + + + + <_r2rSymbolFilePattern>@(ResolvedFileToPublish->'%(RootDir)%(Directory)%(FileName).ni.*.map') + + + + + + + + + + + + + + + + runtimes/$(RuntimeIdentifier)/lib/$(TargetFramework) + runtimes/$(RuntimeIdentifier)/native + + + %(FilesToPackage.TargetPath)/%(FilesToPackage.DestinationSubDirectory) + + + + + + ref/$(TargetFramework) + + + + + + + ref/$(TargetFramework)/%(RecursiveDir) + + + + + + true + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + <_FilesForDepsFile Include="@(FilesToPackage)" Condition="'%(FilesToPackage.IsSymbolFile)' != 'true'" /> + + + + + + <_SharedFrameworkDepsFile> + runtimes/$(RuntimeIdentifier)/lib/$(TargetFramework) + true + + + + + + + + + true + + $(IntermediateOutputPath)$(SharedFrameworkName).runtimeconfig.json + + + + + + + + + + + + + <_PackagedFileNames Include="@(FilesToPackage->'%(Filename)%(Extension)')" + Condition="'%(FilesToPackage.IsSymbolFile)' != 'true' + and '%(FilesToPackage.GeneratedBuildFile)' != 'true' + and $([System.String]::new('%(FilesToPackage.TargetPath)').StartsWith('runtimes/'))" + OriginalFilePath="$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '%(Identity)'))" /> + + + + + + + + + + + $(FileVersion) + $(AssemblyVersion) + + + + + <_FilesMissingInManifestEntries Include="@(_PackagedFileNamesFiltered)" Exclude="@(PlatformManifestFileEntry)" /> + + + + + + + + + + + + + + + + + + + <_RuntimePackHarvestProperties Condition="'$(RuntimePackPlatformForManifest)' != ''">RuntimeIdentifier=$(RuntimePackPlatformForManifest) + <_RuntimePackBuildTarget>_GetPackagedFileNamesNoDuplicates + + + + + + + + + + <_RuntimePackHarvestProperties>$(_RuntimePackHarvestProperties);InnerTargets=$(_RuntimePackBuildTarget) + <_RuntimePackBuildTarget>Build + + + + + + + + + + + + + + + + + + <_PlatformManifestFile Include="$(IntermediateOutputPath)PlatformManifest.txt" TargetPath="data" GeneratedBuildFile="true" /> + + + + + + + + + + + + + + <_FrameworkRuntimeList Include="$(IntermediateOutputPath)FrameworkList.xml" + Condition="'$(PlatformPackageType)' == 'TargetingPack'" /> + <_FrameworkRuntimeList Include="$(IntermediateOutputPath)RuntimeList.xml" + Condition="'$(PlatformPackageType)' == 'RuntimePack'" /> + <_FrameworkRuntimeList> + data + + + <_FrameworkListRootAttribute Include="TargetFrameworkIdentifier" Value="$(TargetFrameworkIdentifier)" /> + <_FrameworkListRootAttribute Include="TargetFrameworkVersion" Value="$(TargetFrameworkVersion.TrimStart('vV'))" /> + <_FrameworkListRootAttribute Include="FrameworkName" Value="$(SharedFrameworkName)" /> + <_FrameworkListRootAttribute Include="Name" Value="$(SharedFrameworkFriendlyName)" /> + <_FrameworkListTargetFilePrefix Include="ref/;runtimes/" /> + + + + + + + + + + + + + data + + + + + + + + <_VersionsFile Include="$(IntermediateOutputPath)$(SharedFrameworkName).versions.txt" TargetPath="" GeneratedBuildFile="true" /> + + + + + + + + + + + + + + + + + + runtimes/$(RuntimeIdentifier)/lib + true + + + <_PackageFiles Include="@(_FilesToPackage)" PackagePath="%(_FilesToPackage.TargetPath)" Condition="'%(_FilesToPackage.IsSymbolFile)' != 'true'" /> + + <_TargetPathsToSymbols Include="@(_FilesToPackage)" + Condition="'%(_FilesToPackage.IsSymbolFile)' == 'true'" + TargetFramework="$(TargetFramework)" + TargetPath="$([MSBuild]::MakeRelative($([MSBuild]::NormalizePath('$(BuildOutputTargetFolder)/$(TargetFramework)')), $([MSBuild]::NormalizePath('%(_FilesToPackage.TargetPath)', '%(Filename)%(Extension)'))))"/> + + + + + + + + + + + + + <_PackagedFilesToPublish Include="@(_FilesToPackage)" Condition="'%(_FilesToPackage.PackOnly)' != 'true'" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/ + <_ArchiveFileName>$(SharedFrameworkArchiveName)-$(Version) + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version) + + + + + + + + + + + <_SharedFrameworkSymbolsOutputPathRoot>$(IntermediateOutputPath)sharedFrameworkSymbols/ + <_ArchiveFileName>$(SharedFrameworkSymbolsArchiveName)-$(Version) + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version) + + + + + + + + + + + $(BuildDependsOn); + _CreateSharedFrameworkArchive; + _CreateSharedFrameworkSymbolsArchive + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs new file mode 100644 index 00000000000..42a1a4db80f --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs @@ -0,0 +1,85 @@ + + + + + + + + + ((VersionNT > v6.1) OR (VersionNT = v6.1 AND ServicePackLevel >= 1)) + + + + + VersionNT64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eula.rtf + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/dummyEula.rtf b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/dummyEula.rtf new file mode 100644 index 00000000000..ebcd5ac373f --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/dummyEula.rtf @@ -0,0 +1,237 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;} +{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f376\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f377\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f379\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f380\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f381\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f382\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f383\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f384\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f376\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f377\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f379\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f380\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f381\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f382\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f383\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f384\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f746\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f747\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\f749\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f750\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f751\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f752\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);} +{\f753\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f754\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;} +{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);} +{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} +{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} +{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} +{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; +\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 +\ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused +Normal Table;}{\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \slink16 \sunhideused \styrsid10564401 header;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 +\sbasedon10 \slink15 \slocked \styrsid10564401 Header Char;}{\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext17 \slink18 \sunhideused \styrsid10564401 footer;}{\*\cs18 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 +\sbasedon10 \slink17 \slocked \styrsid10564401 Footer Char;}}{\*\rsidtbl \rsid2163051\rsid10564401}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim0}{\info +{\operator Rakesh Ranjan Singh}{\creatim\yr2017\mo5\dy30\hr17\min38}{\revtim\yr2017\mo5\dy30\hr17\min39}{\version2}{\edmins1}{\nofpages1}{\nofwords28}{\nofchars160}{\nofcharsws187}{\vern37}}{\*\userprops {\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85 +995028c_Enabled}\proptype30{\staticval True}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId}\proptype30{\staticval 72f988bf-86f1-41af-91ab-2d7cd011db47}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Ref}\proptype30 +{\staticval https://api.informationprotection.azure.com/api/72f988bf-86f1-41af-91ab-2d7cd011db47}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetBy}\proptype30{\staticval raksingh@microsoft.com}{\propname MSIP_Label_f42aa342-8706-4288-bd11-e +bb85995028c_SetDate}\proptype30{\staticval 2017-05-30T17:39:57.6592568-07:00}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name}\proptype30{\staticval General}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Application}\proptype30 +{\staticval Microsoft Azure Information Protection}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Extended_MSFT_Method}\proptype30{\staticval Automatic}{\propname Sensitivity}\proptype30{\staticval General}}{\*\xmlnstbl {\xmlns1 http://schemas +.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701 +\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot10564401 \nouicompat \fet0{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0{\*\ftnsep \ltrpar \pard\plain \ltrpar +\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 { +\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsepc +\par }}\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\headerl \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401 +\par }}{\headerr \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401 +\par }}{\footerl \ltrpar \pard\plain \ltrpar\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401 +\par }}{\footerr \ltrpar \pard\plain \ltrpar\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401 +\par }}{\headerf \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401 +\par }}{\footerf \ltrpar \pard\plain \ltrpar\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401 +\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} +{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa160\sl259\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 +\af31507 \ltrch\fcs0 \insrsid10564401 \hich\af31506\dbch\af31505\loch\f31506 This is a dummy file for Eula as required by \hich\af31506\dbch\af31505\loch\f31506 B\hich\af31506\dbch\af31505\loch\f31506 urn bundle \hich\af31506\dbch\af31505\loch\f31506 +. The bal.WixStandardBootstrapperApplication element must hav a value for exactly one of the LicenseFile or LicenseUrl attributes.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051\charrsid10564401 +\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a +9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad +5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 +b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 +0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 +a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f +c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 +0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 +a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b +4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b +4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b6f4679893070000c9200000160000007468656d652f7468656d652f +7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f2a24fcfda33b6b164873dd648a5eef2547789aad28cc56208de532e81c026e49085bd +ed21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c99e191c3061463074977eefd5afde7bf5de53d5ddcf5e26d4bbc05c1096f6fcfa9d9aefe174ce16248d +7afeb3d9a4d2f13d2151ba4094a5b8e76fb0f03fbbf7eb5fdd454732c609f6403e1547a8e7c752ae8eaa5531876124eeb0154ee1bb25e30992f0caa3ea82a34b +d09bd06aa3566b55134452df4b51026a1f2f97648ebd9952e9dfdb2a1f53784da5500373caa74a35b6243476715e5708b11143cabd0b447b3eccb3609733fc52 +fa1e4542c2173dbfa6fffceabdbb5574940b517940d6909be8bf5c2e17589c37f49c3c3a2b260d823068f50bfd1a40e53e6edc1eb7c6ad429f06a0f91c569a71 +b175b61bc320c71aa0ecd1a17bd41e35eb16ded0dfdce3dc0fd5c7c26b50a63fd8c34f2643b0a285d7a00c1feee1c3417730b2f56b50866fede1dbb5fe28685b +fa3528a6243ddf43d7c25673b85d6d0159327aec8477c360d26ee4ca4b144443115d6a8a254be5a1584bd00bc6270050408a24493db959e1259a43140f112567 +9c7827248a21f056286502866b8ddaa4d684ffea13e827ed5174849121ad780113b137a4f87862cec94af6fc07a0d537206f7ffef9cdeb1fdfbcfee9cd575fbd +79fdf77c6eadca923b466964cafdf2dd1ffef3cd6fbd7ffff0ed2f5fff319b7a172f4cfcbbbffdeedd3ffef93ef5b0e2d2146ffff4fdbb1fbf7ffbe7dfffebaf +5f3bb4f7393a33e1339260e13dc297de5396c0021dfcf119bf9ec42c46c494e8a791402952b338f48f656ca11f6d10450edc00db767cce21d5b880f7d72f2cc2 +d398af2571687c182716f094313a60dc6985876a2ec3ccb3751ab927e76b13f714a10bd7dc43945a5e1eaf579063894be530c616cd2714a5124538c5d253dfb1 +738c1dabfb8210cbaea764ce99604be97d41bc01224e93ccc899154da5d03149c02f1b1741f0b7659bd3e7de8051d7aa47f8c246c2de40d4417e86a965c6fb68 +2d51e252394309350d7e8264ec2239ddf0b9891b0b099e8e3065de78818570c93ce6b05ec3e90f21cdb8dd7e4a37898de4929cbb749e20c64ce4889d0f6394ac +5cd829496313fbb938871045de13265df05366ef10f50e7e40e941773f27d872f787b3c133c8b026a53240d4376beef0e57dccacf89d6ee8126157aae9f3c44a +b17d4e9cd131584756689f604cd1255a60ec3dfbdcc160c05696cd4bd20f62c82ac7d815580f901dabea3dc5027a25d5dcece7c91322ac909de2881de073bad9 +493c1b9426881fd2fc08bc6eda7c0ca52e7105c0633a3f37818f08f480102f4ea33c16a0c308ee835a9fc4c82a60ea5db8e375c32dff5d658fc1be7c61d1b8c2 +be04197c6d1948eca6cc7b6d3343d49aa00c9819822ec3956e41c4727f29a28aab165b3be596f6a62ddd00dd91d5f42424fd6007b4d3fb84ffbbde073a8cb77f +f9c6b10f3e4ebfe3566c25ab6b763a8792c9f14e7f7308b7dbd50c195f904fbfa919a175fa04431dd9cf58b73dcd6d4fe3ffdff73487f6f36d2773a8dfb8ed64 +7ce8306e3b99fc70e5e3743265f3027d8d3af0c80e7af4b14f72f0d46749289dca0dc527421ffc08f83db398c0a092d3279eb838055cc5f0a8ca1c4c60e1228e +b48cc799fc0d91f134462b381daafb4a492472d591f0564cc0a1911e76ea5678ba4e4ed9223becacd7d5c16656590592e5782d2cc6e1a04a66e856bb3cc02bd4 +6bb6913e68dd1250b2d721614c6693683a48b4b783ca48fa58178ce620a157f65158741d2c3a4afdd6557b2c805ae115f8c1edc1cff49e1f06200242701e07cd +f942f92973f5d6bbda991fd3d3878c69450034d8db08283ddd555c0f2e4fad2e0bb52b78da2261849b4d425b46377822869fc17974aad1abd0b8aeafbba54b2d +7aca147a3e08ad9246bbf33e1637f535c8ede6069a9a9982a6de65cf6f35430899395af5fc251c1ac363b282d811ea3717a211dcbccc25cf36fc4d32cb8a0b39 +4222ce0cae934e960d122231f728497abe5a7ee1069aea1ca2b9d51b90103e59725d482b9f1a3970baed64bc5ce2b934dd6e8c284b67af90e1b35ce1fc568bdf +1cac24d91adc3d8d1797de195df3a708422c6cd795011744c0dd413db3e682c0655891c8caf8db294c79da356fa3740c65e388ae62945714339967709dca0b3a +faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca2aaa6abab39835c3b60cecd8f26645de60b53531e434b3c2 +67a97b37e576b7b96ea74f28aa0418bcb09fa3ea5ea12018d4cac92c6a8af17e1a56393b1fb56bc776811fa07695226164fdd656ed8edd8a1ae19c0e066f54f9 +416e376a6168b9ed2bb5a5f5adb979b1cdce5e40f2184197bba6526857c2c92e47d0104d754f92a50dd8222f65be35e0c95b73d2f3bfac85fd60d80887955a27 +1c57826650ab74c27eb3d20fc3667d1cd66ba341e31514161927f530bbb19fc00506dde4f7f67a7cefee3ed9ded1dc99b3a4caf4dd7c5513d777f7f5c6e1bb7b +8f40d2f9b2d598749bdd41abd26df627956034e854bac3d6a0326a0ddba3c9681876ba9357be77a1c141bf390c5ae34ea5551f0e2b41aba6e877ba9576d068f4 +8376bf330efaaff23606569ea58fdc16605ecdebde7f010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65 +2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36 +3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e +3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985 +0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000000000 +0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000 +000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019020000 +7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b6f4679893070000c92000001600000000000000 +000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000 +000000000000000000009d0a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980b00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax375\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong; +\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Table;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text; +\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2; +\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List; +\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1; +\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision; +\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1; +\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1; +\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2; +\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; +\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3; +\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4; +\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4; +\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5; +\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; +\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; +\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; +\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; +\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; +\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; +\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; +\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; +\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; +\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; +\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;}}{\*\datastore 010500000200000018000000 +4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000b00a +ec6da6d9d201feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/eula.rtf b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/eula.rtf new file mode 100644 index 00000000000..7f40e11a8ab --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/eula.rtf @@ -0,0 +1,97 @@ +{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\froman\fprq2\fcharset0 Times New Roman;}{\f3\fswiss\fprq2\fcharset0 Calibri;}} +{\colortbl ;\red0\green0\blue0;\red0\green0\blue255;} +{\*\generator Riched20 10.0.10586}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1 +\pard\widctlpar\sb120\sa120\cf1\b\f0\fs24 MICROSOFT SOFTWARE LICENSE TERMS\fs28\par +\fs24 MICROSOFT .NET LIBRARY\fs28\par +\fs19 These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. Please read them. They apply to the software named above, which includes the media on which you received it, if any. The terms also apply to any Microsoft\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\b0\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 updates,\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 supplements,\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 Internet-based services, and\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 support services\par + +\pard\widctlpar\sb120\sa120\b for this software, unless other terms accompany those items. If so, those terms apply.\par +BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\par +IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE PERPETUAL RIGHTS BELOW.\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\fs20 1.\b0\f2\fs14\~\~\~\~\b\f0\fs19 INSTALLATION AND USE RIGHTS.\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\fs20 a.\b0\f2\fs14\~\~\~\~\b\f0\fs19 Installation and Use.\b0\fs20\~You may install and use any number of copies of the software to design, develop and test your programs.\b\fs19\par +\fs20 b.\b0\f2\fs14\~\~\~\~\b\f0\fs19 Third Party Programs.\b0\fs20\~The software may include third party programs that Microsoft, not the third party, licenses to you under this agreement. Notices, if any, for the third party program are included for your information only.\b\fs19\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\fs20 2.\b0\f2\fs14\~\~\~\~\b\f0\fs19 DATA.\~\kerning0\b0\fs20 The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to improve our products and services.\~You can learn more about data collection and use in the help documentation and the privacy statement at\~{\cf0\f3\fs24{\field{\*\fldinst{HYPERLINK "http://go.microsoft.com/fwlink/?LinkId=528096&clcid=0x409"}}{\fldrslt{\ul\cf2\cf2\ul\f0\fs20 http://go.microsoft.com/fwlink/?LinkId=528096}}}}\f0\fs20 . Your use of the software operates as your consent to these practices.\kerning36\b\fs19\par +\fs20 3.\b0\f2\fs14\~\~\~\~\b\f0\fs20 ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.\fs19\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\fs20 a.\b0\f2\fs14\~\~\~\~\b\f0\fs20 DISTRIBUTABLE CODE.\~\~\b0 The software is comprised of Distributable Code. \ldblquote Distributable Code\rdblquote is code that you are permitted to distribute in programs you develop if you comply with the terms below.\b\fs19\par + +\pard\widctlpar\fi-357\li1077\sb120\sa120\fs20 i.\b0\f2\fs14\~\~\~\~\~\~\b\f0\fs20 Right to Use and Distribute.\b0\fs19\par + +\pard\widctlpar\fi-357\li1434\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 You may copy and distribute the object code form of the software.\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.\fs19\par + +\pard\widctlpar\fi-357\li1077\sb120\sa120\b\fs20 ii.\b0\f2\fs14\~\~\~\~\b\f0\fs20 Distribution Requirements.\b0\~\b For any Distributable Code you distribute, you must\b0\fs19\par + +\pard\widctlpar\fi-357\li1434\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 add significant primary functionality to it in your programs;\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 require distributors and external end users to agree to terms that protect it at least as much as this agreement;\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 display your valid copyright notice on your programs; and\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 indemnify, defend, and hold harmless Microsoft from any claims, including attorneys\rquote fees, related to the distribution or use of your programs.\fs19\par + +\pard\widctlpar\fi-357\li1077\sb120\sa120\b\fs20 iii.\b0\f2\fs14\~\~\~\b\f0\fs20 Distribution Restrictions.\b0\~\b You may not\b0\fs19\par + +\pard\widctlpar\fi-357\li1434\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 alter any copyright, trademark or patent notice in the Distributable Code;\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 use Microsoft\rquote s trademarks in your programs\rquote names or in a way that suggests your programs come from or are endorsed by Microsoft;\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 include Distributable Code in malicious, deceptive or unlawful programs; or\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that\fs19\par + +\pard\widctlpar\fi-358\li1792\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 the code be disclosed or distributed in source code form; or\fs19\par +\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 others have the right to modify it.\fs19\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\b\fs20 4.\b0\f2\fs14\~\~\~\~\b\f0\fs19 SCOPE OF LICENSE.\~\b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\b\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\b0\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 work around any technical limitations in the software;\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 publish the software for others to copy;\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 rent, lease or lend the software;\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 transfer the software or this agreement to any third party; or\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 use the software for commercial software hosting services.\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\b\fs20 5.\b0\f2\fs14\~\~\~\~\b\f0\fs19 BACKUP COPY.\~\b0 You may make one backup copy of the software. You may use it only to reinstall the software.\b\par +\fs20 6.\b0\f2\fs14\~\~\~\~\b\f0\fs19 DOCUMENTATION.\~\b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\b\par +\fs20 7.\b0\f2\fs14\~\~\~\~\b\f0\fs19 EXPORT RESTRICTIONS.\~\b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see\~{\cf0\fs20{\field{\*\fldinst{HYPERLINK www.microsoft.com/exporting }}{\fldrslt{www.microsoft.com/exporting\ul0\cf0}}}}\f0\fs19 .\b\par +\fs20 8.\b0\f2\fs14\~\~\~\~\b\f0\fs19 SUPPORT SERVICES.\~\b0 Because this software is \ldblquote as is,\rdblquote we may not provide support services for it.\b\par +\fs20 9.\b0\f2\fs14\~\~\~\~\b\f0\fs19 ENTIRE AGREEMENT.\~\b0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\b\par +\fs20 10.\b0\f2\fs14\~\~\~\b\f0\fs19 APPLICABLE LAW.\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\fs20 a.\b0\f2\fs14\~\~\~\~\b\f0\fs19 United States.\~\b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\b\par +\fs20 b.\b0\f2\fs14\~\~\~\~\b\f0\fs19 Outside the United States. If you acquired the software in any other country, the laws of that country apply.\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\fs20 11.\b0\f2\fs14\~\~\b\f0\fs19 LEGAL EFFECT.\~\b0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\b\par +\fs20 12.\b0\f2\fs14\~\~\b\f0\fs19 DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED \ldblquote AS-IS.\rdblquote YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS OR STATUTORY GUARANTEES UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\par + +\pard\widctlpar\li357\sb120\sa120\kerning0 FOR AUSTRALIA \endash YOU HAVE STATUTORY GUARANTEES UNDER THE AUSTRALIAN CONSUMER LAW AND NOTHING IN THESE TERMS IS INTENDED TO AFFECT THOSE RIGHTS.\b0\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\b\fs20 13.\b0\f2\fs14\~\~\b\f0\fs19 LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.\par + +\pard\widctlpar\li357\sb120\sa120\kerning0\b0 This limitation applies to\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\par +\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\par + +\pard\widctlpar\sb120\sa120 It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\par +\lang9 Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\lang1033\par +\lang9 Remarque : Ce logiciel \'e9tant distribu\'e9 au Qu\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\'e7ais.\lang1033\par +\kerning36\b EXON\'c9RATION DE GARANTIE.\~\b0 Le logiciel vis\'e9 par une licence est offert \'ab tel quel \'bb. Toute utilisation de ce logiciel est \'e0 votre seule risque et p\'e9ril. Microsoft n\rquote accorde aucune autre garantie expresse. Vous pouvez b\'e9n\'e9ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\'e9 marchande, d\rquote ad\'e9quation \'e0 un usage particulier et d\rquote absence de contrefa\'e7on sont exclues.\b\par +LIMITATION DES DOMMAGES-INT\'c9R\'caTS ET EXCLUSION DE RESPONSABILIT\'c9 POUR LES DOMMAGES.\~\b0 Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\'e9tendre \'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\'e9ciaux, indirects ou accessoires et pertes de b\'e9n\'e9fices.\b\par +\kerning0\b0\lang9 Cette limitation concerne :\lang1033\par + +\pard\widctlpar\li720\sb120\f1\lang9\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 tout ce qui est reli\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\lang1033\par + +\pard\widctlpar\li720\sa120\f1\lang9\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 les r\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\'e9 stricte, de n\'e9gligence ou d\rquote une autre faute dans la limite autoris\'e9e par la loi en vigueur.\lang1033\par + +\pard\widctlpar\sb120\sa120\lang9 Elle s\rquote applique \'e9galement, m\'eame si Microsoft connaissait ou devrait conna\'eetre l\rquote\'e9ventualit\'e9 d\rquote un tel dommage. Si votre pays n\rquote autorise pas l\rquote exclusion ou la limitation de responsabilit\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l\rquote exclusion ci-dessus ne s\rquote appliquera pas \'e0 votre \'e9gard.\lang1033\par +\kerning36\b EFFET JURIDIQUE.\~\b0 Le pr\'e9sent contrat d\'e9crit certains droits juridiques. Vous pourriez avoir d\rquote autres droits pr\'e9vus par les lois de votre pays. Le pr\'e9sent contrat ne modifie pas les droits que vous conf\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\b\par +\kerning0\fs20\lang1036\~\fs19\lang1033\par + +\pard\widctlpar\cf0\b0\f3\fs24\par +} + \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/breadcrumbstorefolder.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/breadcrumbstorefolder.wxs new file mode 100644 index 00000000000..006303058b2 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/breadcrumbstorefolder.wxs @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi new file mode 100644 index 00000000000..463468fe74a --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.wxs new file mode 100644 index 00000000000..1bf18ed9e2d --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.wxs @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/provider.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/provider.wxs new file mode 100644 index 00000000000..5fe17f2a73c --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/provider.wxs @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/registrykeys.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/registrykeys.wxs new file mode 100644 index 00000000000..5711e2a38ba --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/registrykeys.wxs @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/sharedfxdir.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/sharedfxdir.wxs new file mode 100644 index 00000000000..49c02a53ee1 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/sharedfxdir.wxs @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/werrelatedkeys.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/werrelatedkeys.wxs new file mode 100644 index 00000000000..997df3d42bd --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/werrelatedkeys.wxs @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi new file mode 100644 index 00000000000..a57061a1377 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/vs/VS.Redist.Common.Component.nuspec.txt b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/vs/VS.Redist.Common.Component.nuspec.txt new file mode 100644 index 00000000000..e9bb74c1aa4 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/vs/VS.Redist.Common.Component.nuspec.txt @@ -0,0 +1,18 @@ + + + + $COMPONENT_NAME$ + 1.0.0 + $COMPONENT_NAME$ + Microsoft + Microsoft + https://www.microsoft.com/net/dotnet_library_license.htm + $PROJECT_URL$ + true + $FRIENDLY_NAME$ ($ARCH$) Windows Installer MSI as a .nupkg for internal Visual Studio build consumption + © Microsoft Corporation. All rights reserved. + + + + + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets new file mode 100644 index 00000000000..92ec0f909b8 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets @@ -0,0 +1,540 @@ + + + + + + + + + + + + + + + + + + + <_WixIntermediateOutputPath>$(BaseIntermediateOutputPath)wix + + + + 3.10.4 + $(BaseIntermediateOutputPath)WixTools.$(WixVersion)/ + + $(WixToolsDir) + $(WixToolsDir)wix.targets + $(IntermediateOutputPath)/wix/ + $(IntermediateOutputPath)/$(InstallerRuntimeIdentifier)/wix/ + $(IntermediateOutputPath)/lightcommand/ + $(InstallerTargetArchitecture) + + $(MSBuildThisFileDirectory)..\acquisition\acquire-wix\acquire-wix.proj + wix.$(WixVersion).zip + https://dotnetcli.azureedge.net/build/wix/$(WixDownloadFilename) + $(WixToolsDir)$(WixDownloadFilename) + $(WixToolsDir)WixDownload.$(WixVersion).sentinel + + + + + + 5 + + 1996-04-01 + + + + + + + + + + + + + + + + + + $(BundleInstallerUpgradeCodeSeed) $(MajorVersion).$(MinorVersion) $(RuntimeIdentifier) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/ + PackSrc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_OutInstallerFile>$(_InstallerFile) + + + + + + + <_OutInstallerFile Condition="'$(_OutInstallerFile)' == ''">$(_InstallerFile) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(InstallerName.Replace('-', '_')) + sharedfx\$(SharedFrameworkName) + + + + + + + + + + + + + + + + + + + + + + + + <_wixArgs> + <_wixArgs>$(_wixArgs) -nologo + <_wixArgs>$(_wixArgs) -arch $(MsiArch) + <_wixArgs>$(_wixArgs) -out "$(WixObjDir)" + + <_wixArgs>$(_wixArgs) @(WixExtensions -> '-ext %(Identity)', ' ') + <_wixArgs>$(_wixArgs) @(CandleVariables -> '-d%(Identity)="%(Value)"', ' ') + <_wixArgs>$(_wixArgs) @(WixSrcFile -> '"%(FullPath)"', ' ') + <_wixArgs>$(_wixArgs) @(DirectoryToHarvest -> '"%(WixSourceFile)"', ' ') + + + + + + + + <_wixArgs> + <_wixArgs>$(_wixArgs) -nologo + <_wixArgs>$(_wixArgs) -cultures:en-us + <_wixArgs>$(_wixArgs) -out $(_OutInstallerFile) + + <_wixArgs>$(_wixArgs) @(WixExtensions -> '-ext %(Identity)', ' ') + <_wixArgs>$(_wixArgs) @(WixSrcFile -> '"$(WixObjDir)%(Filename).wixobj"', ' ') + <_wixArgs>$(_wixArgs) @(DirectoryToHarvest -> '"%(WixObjFile)"', ' ') + <_lightCommand>light.exe $(_wixArgs) + + <_LightCommandPackagesDir>$(ArtifactsNonShippingPackagesDir) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(MSBuildThisFileDirectory)..\acquisition\acquire-nuget-exe\acquire-nuget-exe.proj + + https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe + $(BaseIntermediateOutputPath)nuget\ + $(NuGetExeToolDir)NuGet.exe + + + + + + VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion) + $(ArtifactsNonShippingPackagesDir)$(VSInsertionComponentName).$(Version).nupkg + + + $(MSBuildThisFileDirectory)vs\VS.Redist.Common.Component.nuspec.txt + $(IntermediateOutputPath)vs\VS.Redist.Common.Component.nuspec + + + $(PackProperties)COMPONENT_MSI=$(ComponentMsiFile); + $(PackProperties)ARCH=$(MsiArch); + $(PackProperties)COMPONENT_NAME=$(VSInsertionComponentName); + $(PackProperties)FRIENDLY_NAME=$(ProductBrandName); + $(PackProperties)PROJECT_URL=$(RepositoryUrl); + + + $(PackArgs) $(VsInsertionNuspecFile) + $(PackArgs) -Version $(Version) + $(PackArgs) -OutputDirectory $(ArtifactsNonShippingPackagesDir) + $(PackArgs) -NoDefaultExcludes + $(PackArgs) -NoPackageAnalysis + $(PackArgs) -Properties "$(PackProperties)" + + + + + + + + + + + + + + + + + + + + + + From 6399975fa0bd5a1f1585343770858e06504e407a Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 29 Jun 2020 09:34:35 -0700 Subject: [PATCH 02/46] Port #5688 to the new SDK. --- .../Microsoft.DotNet.SharedFramework.Sdk.targets | 2 +- .../targets/windows/bundle/bundle.wxs | 2 +- .../targets/windows/product/product.common.wxi | 2 +- .../targets/windows/variables.wxi | 2 +- .../targets/windows/wix.targets | 11 ++++++++++- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 411a57492d8..6b4f1e1011d 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -149,7 +149,7 @@ <_osSupportsWixBasedInstallers Condition="$([MSBuild]::IsOsPlatform(Windows)) and '$(TargetRuntimeOS)' == 'win'">true <_osArchSupportsWixBasedInstallers>$(_osSupportsWixBasedInstallers) - <_osArchSupportsWixBasedInstallers Condition="'$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'arm64'">false + <_osArchSupportsWixBasedInstallers Condition="'$(TargetArchitecture)' == 'arm'">false diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs index 42a1a4db80f..90c44aad03c 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs @@ -18,7 +18,7 @@ ((VersionNT > v6.1) OR (VersionNT = v6.1 AND ServicePackLevel >= 1)) - + VersionNT64 diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi index 463468fe74a..833f564c880 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi @@ -1,7 +1,7 @@ - + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi index a57061a1377..8b781939b73 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi @@ -16,7 +16,7 @@ - + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets index 92ec0f909b8..6845efdf32c 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets @@ -32,7 +32,7 @@ - 3.10.4 + 3.14.0.4118 $(BaseIntermediateOutputPath)WixTools.$(WixVersion)/ $(WixToolsDir) @@ -222,9 +222,18 @@ <_OutInstallerFile Condition="'$(_OutInstallerFile)' == ''">$(_InstallerFile) + + + 500 + 200 + + From 452628d30f725012236f8c41bfe40c6255a15b8e Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 29 Jun 2020 15:46:09 -0700 Subject: [PATCH 03/46] Update readme with documentation of the shared framework generation. Installer and bundle generation docs still TBD. --- .../README.md | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md index eb2545dc910..62b04854c65 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md @@ -1,3 +1,134 @@ # Microsoft.DotNet.SharedFramework.Sdk Common toolset for building shared frameworks and framework packs. + +## Building Framework Packs + +This SDK supports building framework packs based on the [official design](https://github.com/dotnet/designs/blob/master/accepted/2019/targeting-packs-and-runtime-packs.md) as well as additional extensions such as profiles and single-file support. To define a shared framework project, create a project with the `.sfxproj` suffix that references both the `Microsoft.NET.Sdk` and `Microsoft.DotNet.SharedFramework.Sdk` SDKs and defines the name in the `SharedFrameworkName` property and the pack type in the `PlatformPackageType` property. + +An example project is included below: + +```xml + + + + + netcoreapp3.0 + win-x64 + Microsoft.Banana.App + RuntimePack + true + + + + + + + + + + + + + +``` + +This example project shows some of the basic options provided by the SDK. The `SharedFrameworkName` property specifies the name of the shared framework. This is used to determine the NuGet package ID as well as appearing in various data files generated by the build. The `PlatformPackageType` property specifies the type of pack the project defines. There are four types of packs this SDK supports: + +- `RuntimePack`: RID-specific runtime packages +- `TargetingPack`: Packs of reference assemblies +- `AppHostPack`: Pack containing the app hosts +- `ToolPack`: This pack option allows you to have completely custom scripting for what files are included where in your pack. It also enables creating installer-only projects with this SDK. + +This SDK uses the standard mechanisms in the .NET SDK for referencing packages, projects, and other frameworks to resolve its dependencies and collect the files that are a part of the pack. To include native files, add them to the `NativeRuntimeAsset` item group. + +If you need to resolve additional managed assemblies, you can add them to the `ReferenceCopyLocalPaths` item group for runtime packs or `ReferencePath` for targeting packs. XML documentation files can be added to the `DocFilesToPackage` item group. If you need to resolve your assemblies in a target, you can define your own target to resolve them. To enable these files to have ReadyToRun code generated for them for a runtime pack, update the `GetSharedFrameworkFilesForReadyToRunDependsOn` property to include your targets in a semicolon-delimited list. If you are adding additional files to a targeting pack, add `BeforeTargets="GetFilesToPackage"` to the target definition. + +### Platform Manifest generation + +Since platform manifest generation can be tricky at times when a shared framework has differing files per platform, this SDK provides two different mechanisms for generating a platform manifest, templating or harvesting. + +Pros of harvesting: + +- Simple declaration in the project file. + - You define a property in the targeting pack project that points to the runtime pack project. The SDK will determine all of the files that the runtime pack project produces on RIDs that this build will produce. +- Less friction when adding files to the manifest. + - Files will be automatically added by the harvesting process. + +Cons of harvesting: + +- Either all runtime pack RIDs must be buildable from a single invocation or one RID must have a superset of all files in the targeting pack. + +Pros of templating: + +- All files can be declared to be in the manifest without needing every file on disk. +- Targeting pack can be built independently of the runtime pack. +- Ensures that every file in a runtime pack is a known file in the manifest. + +Cons of templating: + +- Each file has to be declared with an MSBuild item. +- File and assembly fallback versions need to be declared for files that do not exist in the targeting pack. +- Any change in the list of files requires a new MSBuild item declaring the entry. + +### Platform Manifest Harvesting + +For platforms where all target platforms have the same files +or where one platform has a superset of the files available +on all platforms, we can generate a platform manifest from +the present files in the runtime pack. + +This is enabled by default or when `UseTemplatedPlatformManifest` is not set to `true`. + +Set the `RuntimePackProjectPath` to the path to the runtime pack shared framework project. + +If you only want to use one RID to generate the platform manifest, you can set +the `RuntimePackPlatformForManifest` property to the RID you'd like to use. +If the chosen RID doesn't have a superset of files for all shipping platforms, +then you may have unexpected behavior when using the produced targeting pack. + +### Templated Platform Manifest + +For shared frameworks with differing sets of files on various platforms +and with no single platform that contains all of the files, this SDK provides support +for creating a platform manifest from a templated list of items. + +Assumptions: + +- All managed assemblies are either present in both the ref and runtime pack for the shared framework + or have an easily calculatable assembly version and file version. +- All native files have an easily calculatable file version. + +To use, set `UseTemplatedPlatformManifes`t to true and define a set of `PlatformManifestFileEntry` items + +`PlatformManifestFileEntry` metadata: + +- `ItemSpec`/`Identity`: File name and extension of file in the shared framework. +- `IsNative`: true when the file is a native file +- `FallbackAssemblyVersion`: An assembly version for this file if it is not present in the ref-pack build. +- `FallbackFileVersion`: A file version for this file if it is not present in the ref-pack build. + +Properties for these targets: +`UseTemplatedPlatformManifest`: Set to true to enable the templated platform manifest generation +`PlatformManifestFallbackAssemblyVersion`: Fallback asssembly version when one is needed and there is no fallback on the entry. +`PlatformManifestFallbackFileVersion`: Fallback file version when one is needed and there is no fallback on the entry. + +### RuntimeList/FrameworkList Generation + +The FrameworkList/RuntimeList support in this SDK has some additions on the base design to support profile and single-file features. + +If your shared framework has various profiles, you can use `` items to specify the profiles for each file in the shared framework. However, once you've specified one `FrameworkListFileClass` entry, you need to specify one for every file in the framework. + +If your shared framework can drop some files from the single-file bundle, you can specify `` items that specify which files by name are **included** in the single file bundle. Once one `SingleFileHostIncludeFilename` item is specified, all files without corresponding `SingleFileHostIncludeFilename` elements will be marked as droppable from a single file build. + +### Archives + +By default, this SDK also generates an archive that can be extracted on top of an existing .NET SDK or Runtime layout. The name of this file is derived from the `SharedFrameworkArchiveName` property and the RID. By default, `SharedFrameworkArchiveName` is set to the value of `SharedFrameworkName`. + +### Custom dumping to disk + +This SDK provides a custom target named `PublishSharedFrameworkToDisk` that publishes the generated framework pack to disk as though the folder specified via the `SharedFrameworkOutputPath` is the root of a .NET SDK or Runtime layout. This target is used internally by the archive and installer generation. Additionally, if you are defining a custom installer project that doesn't use the `.sfxproj` extension (for example if you only need installers and not NuGet packages), you can define your own `PublishSharedFrameworkToDisk` target that publishes your files to disk in the correct layout for the installers to place files in during installation. + +## Building Installers + +## Building Installer Bundles From 564617d9afdca7cbe4f5375167f029adaab0ee57 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 1 Jul 2020 10:47:11 -0700 Subject: [PATCH 04/46] Add back feature that was somehow lost in the rebase. --- .../targets/installer.targets | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets index ee8db9200d1..c07f85bf956 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets @@ -471,9 +471,14 @@ + + <_ShortDescription>$(MSBuildProjectName) $(InstallerPackageVersion) + <_ShortDescription Condition="'$(UseBrandingNameInLinuxPackageDescription)' == 'true'">$(ProductBrandName) + + <_CommonLinuxPackageProperty Include="package_name" String="$(VersionedInstallerName)" /> - <_CommonLinuxPackageProperty Include="short_description" String="$(MSBuildProjectName) $(InstallerPackageVersion)" /> + <_CommonLinuxPackageProperty Include="short_description" String="$(_ShortDescription)" /> <_CommonLinuxPackageProperty Include="maintainer_name" String=".NET Team" /> <_CommonLinuxPackageProperty Include="maintainer_email" String="dotnetpackages@dotnetfoundation.org" /> <_CommonLinuxPackageProperty Include="install_root" String="/usr/share/dotnet" /> From 97dd8ab1521d16912679a181144229a391bd2649 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 1 Jul 2020 16:57:21 -0700 Subject: [PATCH 05/46] Add basic docs for the installer builds. --- .../README.md | 69 +++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md index 62b04854c65..5bff7f91b03 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md @@ -1,6 +1,6 @@ # Microsoft.DotNet.SharedFramework.Sdk -Common toolset for building shared frameworks and framework packs. +This package provides a common set of tools for authoring framework packs, shared frameworks, and packages and installers for packs and frameworks. ## Building Framework Packs @@ -103,10 +103,14 @@ To use, set `UseTemplatedPlatformManifes`t to true and define a set of `Platform `PlatformManifestFileEntry` metadata: -- `ItemSpec`/`Identity`: File name and extension of file in the shared framework. -- `IsNative`: true when the file is a native file -- `FallbackAssemblyVersion`: An assembly version for this file if it is not present in the ref-pack build. -- `FallbackFileVersion`: A file version for this file if it is not present in the ref-pack build. +- `ItemSpec`/`Identity` + - File name and extension of file in the shared framework. +- `IsNative` + - true when the file is a native file +- `FallbackAssemblyVersion` + - An assembly version for this file if it is not present in the ref-pack build. +- `FallbackFileVersion` + - A file version for this file if it is not present in the ref-pack build. Properties for these targets: `UseTemplatedPlatformManifest`: Set to true to enable the templated platform manifest generation @@ -121,6 +125,8 @@ If your shared framework has various profiles, you can use `` items that specify which files by name are **included** in the single file bundle. Once one `SingleFileHostIncludeFilename` item is specified, all files without corresponding `SingleFileHostIncludeFilename` elements will be marked as droppable from a single file build. +The name of the framework/runtime is specified in the `SharedFrameworkFriendlyName` property, which defaults to the value of `SharedFrameworkName`. + ### Archives By default, this SDK also generates an archive that can be extracted on top of an existing .NET SDK or Runtime layout. The name of this file is derived from the `SharedFrameworkArchiveName` property and the RID. By default, `SharedFrameworkArchiveName` is set to the value of `SharedFrameworkName`. @@ -131,4 +137,57 @@ This SDK provides a custom target named `PublishSharedFrameworkToDisk` that publ ## Building Installers +In addition to producing framework packs this SDK also supports generating installers for the shared framework in .msi, .deb, .rpm, and .pkg formats. This support is opt-in by setting the `GenerateInstallers` property to `true`. In addition, to enable the .deb and .rpm support, the `GenerateDebPackage` and `GenerateRpmPackage` properties respectively need to be set to true. This support acts independently of the shared framework support and only depends on the `PublishSharedFrameworkToDisk` target. So, you can use the SDK with a project that has a non-`.sfxproj` extension such as `.proj` or `.installproj` and set `GenerateInstallers` to `true` to opt into only installer generation, as long as you define the `PublishSharedFrameworkToDisk` target. + +There are a few common properties used by all of the installer types and the bundle installers (documented after the installers): + +- `SharedFrameworkInstallerName` + - The name of the installer file without an extension. This defaults to `SharedFrameworkArchiveName`. +- `ProductBrandPrefix` + - The branding name of this component, such as "Microsoft Windows Desktop" +- `PackageBrandNameSuffix` (`ToolPack` installers only) + - The type of package, for example "Shared Host" or "AppHost Pack". This is set automatically for any non-ToolPack package types. + +For correct branding and versioning, this SDK has a dependency on Arcade's versioning setup, including the `MajorVersion`, `MinorVersion`, `PreReleaseVersionLabel`, `PreReleaseVersionIteration` and `DotNetFinalVersionKind` properties. + +Since some framework packs do not use `RuntimeIdentifier`s in their build, for example targeting packs, for the installer build you can define `InstallerRuntimeIdentifiers` and the build will fan out for the installer build across those target RIDs. In addition, the `InstallerRuntimeIdentifier` property will default to the value of `RuntimeIdentifier` if it is not set. + +### Wix MSI configuration + +If you have files that need to have a stabilized identity in the MSI file, you can add items to the `HeatOutputFileElementToStabilize` item group. Each item in this group specifies a unique suffix of a path (enough to identify a single file) and a value for the `ReplacementId` metadata as the id to set in the MSI for this file. + +If you want to create MSIs for the target RID that target other architecture install locations, you can add `CrossArchSdkMsiInstallerArch` items for all of the target architecture install locations you want to generate installers of the current build for. + +### Linux package configuration + +To add package dependencies for linux packages, add a `LinuxPackageDependency` item with the version in the `Version` metadata. + +#### Deb package configuration + +To add additional properties for the deb package tool, add items to the `DebJsonProperty` item group. + +#### Rpm package configuration + +To add additional properties for the deb package tool, add items to the `RpmJsonProperty` item group. + +### MacOS Pkg configuration + +To specify a directory where `pkgbuild` should look for scripts, set the `MacOSScriptsDirectory` to the path to the scripts. + +If you are building a `ToolPack` pack, you need to specify the `MacOSComponentNamePackType` property to create the component name for the `.pkg` package. If you want the component name to not include the version (for example you are building the shared host), you can set the `IncludeVersionInMacOSComponentName` property to false. + +If your `pkg` is later going to be bundled in a macOS `pkg` bundle created by `productbuild`, you should also specify the `MacOSPackageDescription` property, which will set the package description in the bundle distribution file. + +### Visual Studio Insertion Package configuration + +Visual Studio insertion packages generated by the SDK are named in the form `VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion)` + +The `InstallerTargetArchitecture` and later properties are automatically calculated by the SDK or are version properties. You are required to provide the `VSInsertionShortComponentName` property value yourself. + ## Building Installer Bundles + +As part of the installer support, the SDK supports building Wix bundle installers and macOS pkg bundles. These bundles are defined in a separate project with a `.bundleproj` extension that includes the .NET SDK and this SDK as shown in the example project. + +### Wix Bundle configuration + +### MacOS Pkg bundle configuration \ No newline at end of file From 4f6c9569ebcbbbd7e2a54d5a6338c3b8e9bf5137 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 2 Jul 2020 11:14:52 -0700 Subject: [PATCH 06/46] Finish documentation. --- .../README.md | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md index 5bff7f91b03..8f211c3110a 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md @@ -186,8 +186,37 @@ The `InstallerTargetArchitecture` and later properties are automatically calcula ## Building Installer Bundles -As part of the installer support, the SDK supports building Wix bundle installers and macOS pkg bundles. These bundles are defined in a separate project with a `.bundleproj` extension that includes the .NET SDK and this SDK as shown in the example project. +As part of the installer support, the SDK supports building Wix bundle installers and macOS pkg bundles. These bundles are defined in a separate project with a `.bundleproj` extension that includes the .NET SDK and this SDK as shown in the example project. Like the installer targets, the bundle targets also use the `SharedFrameworkName` and `SharedFrameworkInstallerName` properties, as well as the support for `RuntimeIdentifiers` to identify target architectures for the bundle. The bundle targets verify that the RID is targeting an OS that supports an installer bundle, so be sure to limit the RID list to platforms that support bundles (Windows and macOS today). + +The bundle installers also require the `ProductBrandPrefix` property and a `BundleNameSuffix` property in the place of the `PackageBrandNameSuffix` property used by the installer targets. + +To include installers in the bundle, add `BundleComponentReference` items that point to the projects that produce the installers. ### Wix Bundle configuration -### MacOS Pkg bundle configuration \ No newline at end of file +A number of properties are required to configure the Wix bundle generation: + +- `BundleInstallerUpgradeCodeSeed` + - This property specifies a seed for generating the bundle upgrade GUID. This must not change within a product band, otherwise the upgrade code will not match. +- `BundleThemeDirectory` + - This property should point to a directory that contains the following files and folders: + - `bundle.thm` + - `bundle.wxl` + - A `theme` directory that contains subdirectories with resources per codepage. + +### MacOS Pkg bundle configuration + +A number of properties are required to configure the MacOS Pkg bundle generation: + +- `MacOSBundleIdentifierName` + - The identifier of the pkg bundle. +- `MacOSBundleResourcesPath` + - The folder with the resources for the bundle, including various HTML and RTF files that the installer shows the user. +- `MacOSBundleTemplate` + - A partial [macOS Distribution XML file](https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html). The build system will add the ``, `<choices-outline>`, `<choice>`, and `<pkg-ref>` elements automatically to the provided XML file based on the provided properties and the bundled `.pkg` files defined in the project file. + +## Build Skip Support for Unsupported Platforms and Servicing + +This SDK also supports automatically skipping builds on unsupported platforms or in servicing releases. If a project with a list of provided RIDs in `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` is built with the `RuntimeIdentifier` property or `InstallerRuntimeIdentifier` property set to a RID that is not in the `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` list respectively, the build will be skipped. This enables cleanly skipping optional packs, installers, or bundles that only exist on specific platforms. + +Additionally, if a `ProjectServicingConfiguration` item is provided with the identity of the project name and the `PatchVersion` metadata on the item is not equal to the current `PatchVersion`, the build will be skipped. This support enables a repository to disable building targeting packs in servicing releases if that is desired. From a20bef3ee679f040900a852966e9d64c5650e502 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 15 Jul 2020 11:12:53 -0700 Subject: [PATCH 07/46] Update host file names to be overridable to support the crossgen2 pack. --- src/Microsoft.DotNet.SharedFramework.Sdk/README.md | 8 ++++++++ .../src/GenerateSharedFrameworkDepsFile.cs | 8 ++++++-- .../targets/sharedfx.targets | 4 +++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md index 8f211c3110a..047a7d5fc84 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md @@ -44,6 +44,14 @@ This SDK uses the standard mechanisms in the .NET SDK for referencing packages, If you need to resolve additional managed assemblies, you can add them to the `ReferenceCopyLocalPaths` item group for runtime packs or `ReferencePath` for targeting packs. XML documentation files can be added to the `DocFilesToPackage` item group. If you need to resolve your assemblies in a target, you can define your own target to resolve them. To enable these files to have ReadyToRun code generated for them for a runtime pack, update the `GetSharedFrameworkFilesForReadyToRunDependsOn` property to include your targets in a semicolon-delimited list. If you are adding additional files to a targeting pack, add `BeforeTargets="GetFilesToPackage"` to the target definition. +### Deps file generation + +By default, the SDK will generate a .deps.json file for runtime packs named `$(SharedFrameworkName).deps.json`. You can set the `$(SharedFrameworkHostFileNameOverride)` property to instead generate the deps file with the name `$(SharedFrameworkHostFileNameOverride).deps.json`. + +### Runtimeconfig file generation + +This SDK uses the built-in .NET SDK generation for .runtimeconfig.json files for runtime packs. By default, the output file will be named `$(SharedFrameworkName).runtimeconfig.json`. You can override it to be named `$(SharedFrameworkHostFileNameOverride).runtimeconfig.json`. + ### Platform Manifest generation Since platform manifest generation can be tricky at times when a shared framework has differing files per platform, this SDK provides two different mechanisms for generating a platform manifest, templating or harvesting. diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs index e3f07fb74ec..fe3a8a47399 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs @@ -36,6 +36,8 @@ public class GenerateSharedFrameworkDepsFile : BuildTask [Required] public string IntermediateOutputPath { get; set; } + public string SharedFrameworkDepsNameOverride { get; set; } + [Output] public ITaskItem GeneratedDepsFile { get; set; } @@ -62,7 +64,7 @@ public override bool Execute() var nativeFile = new RuntimeFile(fileName, null, fileVersion); nativeFiles.Add(nativeFile); } - else + else if (string.IsNullOrEmpty(file.GetMetadata("GeneratedBuildFile"))) { var runtimeFile = new RuntimeFile(fileName, fileVersion: fileVersion, @@ -89,7 +91,9 @@ public override bool Execute() new[] { runtimeLibrary }, Enumerable.Empty<RuntimeFallbacks>()); - var depsFilePath = Path.Combine(IntermediateOutputPath, $"{SharedFrameworkName}.deps.json"); + var depsFileName = string.IsNullOrEmpty(SharedFrameworkDepsNameOverride) ? $"{SharedFrameworkName}.deps.json" : $"{SharedFrameworkDepsNameOverride}.deps.json"; + + var depsFilePath = Path.Combine(IntermediateOutputPath, depsFileName); try { using var depsStream = File.Create(depsFilePath); diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 3850c7c3337..d2dddd33a48 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -138,7 +138,8 @@ SharedFrameworkPackName="$(PackageId)" Version="$(Version)" Files="@(_FilesForDepsFile)" - IntermediateOutputPath="$(IntermediateOutputPath)"> + IntermediateOutputPath="$(IntermediateOutputPath)" + SharedFrameworkDepsNameOverride="$(SharedFrameworkHostFileNameOverride)"> <Output TaskParameter="GeneratedDepsFile" ItemName="_SharedFrameworkDepsFile" /> </GenerateSharedFrameworkDepsFile> <ItemGroup> @@ -156,6 +157,7 @@ <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> <ProjectRuntimeConfigDevFilePath></ProjectRuntimeConfigDevFilePath> <ProjectRuntimeConfigFilePath>$(IntermediateOutputPath)$(SharedFrameworkName).runtimeconfig.json</ProjectRuntimeConfigFilePath> + <ProjectRuntimeConfigFilePath Condition="'$(SharedFrameworkHostFileNameOverride)' != ''">$(IntermediateOutputPath)$(SharedFrameworkHostFileNameOverride).runtimeconfig.json</ProjectRuntimeConfigFilePath> </PropertyGroup> </Target> From 346b896624e866ee38aaefd93c7b8ddf35fc67d9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 15 Jul 2020 11:47:00 -0700 Subject: [PATCH 08/46] Fix GeneratedBuildFile check in GenerateSharedFrameworkDepsFile --- .../src/GenerateSharedFrameworkDepsFile.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs index fe3a8a47399..50b0b1f9304 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs @@ -50,6 +50,10 @@ public override bool Execute() foreach (var file in Files) { + if (!string.IsNullOrEmpty(file.GetMetadata("GeneratedBuildFile"))) + { + continue; + } var filePath = file.ItemSpec; var fileName = Path.GetFileName(filePath); var fileVersion = FileUtilities.GetFileVersion(filePath)?.ToString() ?? string.Empty; @@ -64,7 +68,7 @@ public override bool Execute() var nativeFile = new RuntimeFile(fileName, null, fileVersion); nativeFiles.Add(nativeFile); } - else if (string.IsNullOrEmpty(file.GetMetadata("GeneratedBuildFile"))) + else { var runtimeFile = new RuntimeFile(fileName, fileVersion: fileVersion, From 18ab7fd4511b0607dd1a1066544c7504fdfef6a9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 15 Jul 2020 13:33:20 -0700 Subject: [PATCH 09/46] Split out the archive targets from the sharedfx targets so installer-only projects can also generate archives. --- ...Microsoft.DotNet.SharedFramework.Sdk.props | 1 + ...crosoft.DotNet.SharedFramework.Sdk.targets | 3 + .../targets/archive.props | 6 ++ .../targets/archive.targets | 56 +++++++++++++++++++ .../targets/sharedfx.targets | 55 ------------------ 5 files changed, 66 insertions(+), 55 deletions(-) create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props index 3a44b5e9f41..21116f67fef 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props @@ -1,4 +1,5 @@ <Project> <Import Project="$(MSBuildThisFileDirectory)sharedfx.props" /> + <Import Project="$(MSBuildThisFileDirectory)archive.props" /> <Import Project="$(MSBuildThisFileDirectory)installer.props" /> </Project> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 6b4f1e1011d..2de4f1529b6 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -133,6 +133,9 @@ <Import Project="$(MSBuildThisFileDirectory)sharedfx.targets" Condition="'$(MSBuildProjectExtension)' == '.sfxproj'" /> + + <Import Project="$(MSBuildThisFileDirectory)archive.targets" + Condition="'$(GenerateArchive)' == 'true'" /> <Target Name="_GetTargetOSArchInfo"> <Error Condition="'$(InstallerRuntimeIdentifier)' == ''" diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props new file mode 100644 index 00000000000..f424c378650 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props @@ -0,0 +1,6 @@ +<Project> + <PropertyGroup> + <!-- Don't generate archives for bundles by default. --> + <GenerateArchive Condition="'$(MSBuildProjectExtension)' != '.bundleproj'">true</GenerateArchive> + </PropertyGroup> +</Project> \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets new file mode 100644 index 00000000000..ebb96887663 --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets @@ -0,0 +1,56 @@ +<Project> + <Target Name="_CreateSharedFrameworkArchive" + DependsOnTargets="_CalculatePackageInformation" + Condition="'$(SkipBuild)' != 'true'"> + <PropertyGroup> + <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/</_SharedFrameworkOutputPathRoot> + <_ArchiveFileName>$(SharedFrameworkArchiveName)-$(Version)</_ArchiveFileName> + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> + </PropertyGroup> + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishSharedFrameworkToDisk" + Properties="SharedFrameworkOutputPath=$(_SharedFrameworkOutputPathRoot)" + RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> + + <MakeDir Directories="$(PackageOutputPath)" /> + <ZipDirectory SourceDirectory="$(_SharedFrameworkOutputPathRoot)" + Overwrite="true" + DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" + Condition="$([MSBuild]::IsOSPlatform(Windows))"/> + <Exec Command="tar -C '$(_SharedFrameworkOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." + IgnoreExitCode="true" + IgnoreStandardErrorWarningFormat="true" + Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> + </Target> + + <Target Name="_CreateSharedFrameworkSymbolsArchive" + DependsOnTargets="_CalculatePackageInformation" + Condition="'$(CreateSharedFrameworkSymbolsArchive)' == 'true' and '$(SkipBuild)' != 'true'"> + <PropertyGroup> + <_SharedFrameworkSymbolsOutputPathRoot>$(IntermediateOutputPath)sharedFrameworkSymbols/</_SharedFrameworkSymbolsOutputPathRoot> + <_ArchiveFileName>$(SharedFrameworkSymbolsArchiveName)-$(Version)</_ArchiveFileName> + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> + </PropertyGroup> + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishSharedFrameworkSymbolsToDisk" + Properties="SharedFrameworkSymbolsOutputPath=$(_SharedFrameworkSymbolsOutputPathRoot)" /> + + <MakeDir Directories="$(PackageOutputPath)" /> + <ZipDirectory SourceDirectory="$(_SharedFrameworkSymbolsOutputPathRoot)" + Overwrite="true" + DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" + Condition="$([MSBuild]::IsOSPlatform(Windows))"/> + <Exec Command="tar -C '$(_SharedFrameworkSymbolsOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." + IgnoreExitCode="true" + IgnoreStandardErrorWarningFormat="true" + Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> + </Target> + + <PropertyGroup> + <BuildDependsOn> + $(BuildDependsOn); + _CreateSharedFrameworkArchive; + _CreateSharedFrameworkSymbolsArchive + </BuildDependsOn> + </PropertyGroup> +</Project> \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index d2dddd33a48..7a43ce22290 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -470,59 +470,4 @@ OverwriteReadOnlyFiles="true" SkipUnchangedFiles="true" /> </Target> - - <Target Name="_CreateSharedFrameworkArchive" - DependsOnTargets="_CalculatePackageInformation" - Condition="'$(SkipBuild)' != 'true'"> - <PropertyGroup> - <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/</_SharedFrameworkOutputPathRoot> - <_ArchiveFileName>$(SharedFrameworkArchiveName)-$(Version)</_ArchiveFileName> - <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> - </PropertyGroup> - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkToDisk" - Properties="SharedFrameworkOutputPath=$(_SharedFrameworkOutputPathRoot)" - RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> - - <MakeDir Directories="$(PackageOutputPath)" /> - <ZipDirectory SourceDirectory="$(_SharedFrameworkOutputPathRoot)" - Overwrite="true" - DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" - Condition="$([MSBuild]::IsOSPlatform(Windows))"/> - <Exec Command="tar -C '$(_SharedFrameworkOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." - IgnoreExitCode="true" - IgnoreStandardErrorWarningFormat="true" - Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> - </Target> - - <Target Name="_CreateSharedFrameworkSymbolsArchive" - DependsOnTargets="_CalculatePackageInformation" - Condition="'$(CreateSharedFrameworkSymbolsArchive)' == 'true' and '$(SkipBuild)' != 'true'"> - <PropertyGroup> - <_SharedFrameworkSymbolsOutputPathRoot>$(IntermediateOutputPath)sharedFrameworkSymbols/</_SharedFrameworkSymbolsOutputPathRoot> - <_ArchiveFileName>$(SharedFrameworkSymbolsArchiveName)-$(Version)</_ArchiveFileName> - <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> - </PropertyGroup> - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkSymbolsToDisk" - Properties="SharedFrameworkSymbolsOutputPath=$(_SharedFrameworkSymbolsOutputPathRoot)" /> - - <MakeDir Directories="$(PackageOutputPath)" /> - <ZipDirectory SourceDirectory="$(_SharedFrameworkSymbolsOutputPathRoot)" - Overwrite="true" - DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" - Condition="$([MSBuild]::IsOSPlatform(Windows))"/> - <Exec Command="tar -C '$(_SharedFrameworkSymbolsOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." - IgnoreExitCode="true" - IgnoreStandardErrorWarningFormat="true" - Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> - </Target> - - <PropertyGroup> - <BuildDependsOn> - $(BuildDependsOn); - _CreateSharedFrameworkArchive; - _CreateSharedFrameworkSymbolsArchive - </BuildDependsOn> - </PropertyGroup> </Project> From 30bd1c8fcb6f2d466e0ba7c9c990f7b1b38202de Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 15 Jul 2020 13:39:48 -0700 Subject: [PATCH 10/46] Fix error condition. --- .../targets/Microsoft.DotNet.SharedFramework.Sdk.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 2de4f1529b6..db2bd229965 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -184,7 +184,7 @@ Condition="'$(ProductBrandPrefix)' == ''" /> <Error Text="When building installers for a tool pack a PackageBrandNameSuffix is required." - Condition="'$(PackageBrandNameSuffix)' == '' and '$(PlatformPackageType)' == 'ToolPack'" /> + Condition="'$(PackageBrandNameSuffix)' == '' and '$(PlatformPackageType)' == 'ToolPack' and '$(MSBuildProjectExtension)' != '.bundleproj'" /> <Error Text="When building a bundle installer, a BundleNameSuffix must be specified." Condition="'$(BundleNameSuffix)' == '' and '$(MSBuildProjectExtension)' == '.bundleproj'" /> From 8ace30a41c431343f0f09f2254da4ea27efd3dab Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 15 Jul 2020 15:41:52 -0700 Subject: [PATCH 11/46] Version 5.0.0-dev.20365.8 Add PackageTargetOS property for the dotnet-runtime-deps packages to hook in to. --- .../targets/installer.targets | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets index c07f85bf956..7881ee06699 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets @@ -130,9 +130,12 @@ <_InstallerIntermediatesDir>$(IntermediateOutputPath)$(InstallerName)/$(InstallerPackageVersion)/</_InstallerIntermediatesDir> <InstallerBuildPart>$(Version)-$(TargetRuntimeOS)-$(InstallerTargetArchitecture)</InstallerBuildPart> - <InstallerBuildPart Condition="'$(GenerateDeb)' == 'true' or '$(GenerateRpm)' == 'true'" - >$(ProductVersion)-$(InstallerTargetArchitecture)</InstallerBuildPart> - + </PropertyGroup> + <PropertyGroup Condition="'$(GenerateDeb)' == 'true' or '$(GenerateRpm)' == 'true'"> + <InstallerBuildPart>$(ProductVersion)-$(InstallerTargetArchitecture)</InstallerBuildPart> + <InstallerBuildPart Condition="'$(PackageTargetOS)' != ''">$(ProductVersion)-$(PackageTargetOS)-$(InstallerTargetArchitecture)</InstallerBuildPart> + </PropertyGroup> + <PropertyGroup> <!-- Location to place the installer, in artifacts. --> <InstallerFileNameWithoutExtension>$(SharedFrameworkInstallerName)-$(InstallerBuildPart)$(CrossArchContentsBuildPart)</InstallerFileNameWithoutExtension> <_InstallerFile Condition="'$(_InstallerFile)' == ''">$(PackageOutputPath)$(InstallerFileNameWithoutExtension)$(InstallerExtension)</_InstallerFile> From 81bd869a397cd659f58cb79f7c2d0243b1b6ac25 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 22 Jul 2020 16:29:31 -0700 Subject: [PATCH 12/46] Only include runtime files in the deps file (not tool files or crosstargeting files). --- .../targets/sharedfx.targets | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 7a43ce22290..4a4c078065f 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -130,7 +130,9 @@ DependsOnTargets="GetFilesToPackage" Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <ItemGroup> - <_FilesForDepsFile Include="@(FilesToPackage)" Condition="'%(FilesToPackage.IsSymbolFile)' != 'true'" /> + <_FilesForDepsFile Include="@(FilesToPackage)" + Condition="'%(FilesToPackage.IsSymbolFile)' != 'true' and + $([System.String]::new('%(FilesToPackage.TargetPath)').StartsWith('runtimes/$(RuntimeIdentifier)'))" /> </ItemGroup> <GenerateSharedFrameworkDepsFile TargetFrameworkMoniker="$(TargetFrameworkMoniker)" RuntimeIdentifier="$(RuntimeIdentifier)" From 4be0523b3dd6560e2811b39cd6740085eec33eb0 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 23 Jul 2020 14:16:00 -0700 Subject: [PATCH 13/46] Exclude PackOnly=true files from the deps file. They won't be available on disk. --- .../targets/sharedfx.targets | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 4a4c078065f..d3367957743 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -132,6 +132,7 @@ <ItemGroup> <_FilesForDepsFile Include="@(FilesToPackage)" Condition="'%(FilesToPackage.IsSymbolFile)' != 'true' and + '%(FilesToPackage.PackOnly)' != 'true' and $([System.String]::new('%(FilesToPackage.TargetPath)').StartsWith('runtimes/$(RuntimeIdentifier)'))" /> </ItemGroup> <GenerateSharedFrameworkDepsFile TargetFrameworkMoniker="$(TargetFrameworkMoniker)" From 45610c55a7fd349a71f171206152bd985ee5a71b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 23 Jul 2020 16:46:41 -0700 Subject: [PATCH 14/46] Fix NuGet package type. --- src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props index a55ad906beb..30d47fc7fdb 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.props @@ -11,6 +11,7 @@ <IsPackable>true</IsPackable> <IncludeSymbols>true</IncludeSymbols> <NoWarn>$(NoWarn);NU5128;NU5131</NoWarn> + <PackageType>DotnetPlatform</PackageType> </PropertyGroup> <!-- Stub out the CreatePackageOverrides target. Each repo uses their own implementation. --> From 93361f5be9888f1a427f3ffe77d13bfeda8e35ee Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 23 Jul 2020 16:47:04 -0700 Subject: [PATCH 15/46] Remove important parameter from error tasks. --- .../targets/installer.targets | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets index 7881ee06699..163326cb2d7 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets @@ -164,8 +164,7 @@ </PropertyGroup> <Error Condition=" '$(_DebuildPresent)' != 'true' " - Text="Debuild Not found, Debian packages will not be built." - Importance="High" /> + Text="Debuild Not found, Debian packages will not be built." /> </Target> <!-- @@ -188,8 +187,7 @@ </PropertyGroup> <Error Condition=" '$(_FPMPresent)' != 'true' " - Text="FPM tool Not found, RPM packages will not be built." - Importance="High" /> + Text="FPM tool Not found, RPM packages will not be built." /> </Target> <!-- From c5565a99396e2dbe8c1561f7f69b43b5fc07b868 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 23 Jul 2020 16:57:25 -0700 Subject: [PATCH 16/46] Allow files to be individually opted-out of being added to the deps file and platform manifest via the ExcludeFromDataFiles metadata. This should only be used for text files (such as native header files) that are included in packs but are never resolved by the hosting or sdk layers. --- .../targets/sharedfx.targets | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index d3367957743..8a1096b8e5f 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -133,6 +133,7 @@ <_FilesForDepsFile Include="@(FilesToPackage)" Condition="'%(FilesToPackage.IsSymbolFile)' != 'true' and '%(FilesToPackage.PackOnly)' != 'true' and + '%(FilesToPackage.ExcludeFromDataFiles)' != 'true' and $([System.String]::new('%(FilesToPackage.TargetPath)').StartsWith('runtimes/$(RuntimeIdentifier)'))" /> </ItemGroup> <GenerateSharedFrameworkDepsFile TargetFrameworkMoniker="$(TargetFrameworkMoniker)" @@ -183,9 +184,10 @@ participate in reference resolution. We also don't want to include generated json files since they're not included in reference resolution.--> <_PackagedFileNames Include="@(FilesToPackage->'%(Filename)%(Extension)')" - Condition="'%(FilesToPackage.IsSymbolFile)' != 'true' - and '%(FilesToPackage.GeneratedBuildFile)' != 'true' - and $([System.String]::new('%(FilesToPackage.TargetPath)').StartsWith('runtimes/'))" + Condition="'%(FilesToPackage.IsSymbolFile)' != 'true' and + '%(FilesToPackage.GeneratedBuildFile)' != 'true' and + '%(FilesToPackage.ExcludeFromDataFiles)' != 'true' and + $([System.String]::new('%(FilesToPackage.TargetPath)').StartsWith('runtimes/'))" OriginalFilePath="$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '%(Identity)'))" /> </ItemGroup> From 3bfd295d084f9e17fba853d391d17824b4711771 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Mon, 27 Jul 2020 09:40:39 -0700 Subject: [PATCH 17/46] Reduce copying and enable empty installers for linux. --- .../targets/installer.targets | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets index 163326cb2d7..76621696b3a 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets @@ -397,15 +397,6 @@ Create installer layout. Used for RPM and Deb package creation. --> <Target Name="_CreateInstallerLayout"> - <PropertyGroup> - <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/</_SharedFrameworkOutputPathRoot> - </PropertyGroup> - - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkToDisk" - Properties="SharedFrameworkOutputPath=$(_SharedFrameworkOutputPathRoot)" - RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> - <PropertyGroup> <_LayoutDirectory>$(IntermediateOutputPath)installer/layoutDirectory/</_LayoutDirectory> <_LayoutPackageRoot>$(_LayoutDirectory)package_root</_LayoutPackageRoot> @@ -425,15 +416,10 @@ <MakeDir Directories="$(_LayoutSamples)" /> <MakeDir Directories="$(_LayoutDocs)" /> - <ItemGroup> - <_LayoutFiles Include="$(_SharedFrameworkOutputPathRoot)/**/*" /> - </ItemGroup> - - <Error Text="No pack layout files found, expected > 0." Condition="@(_LayoutFiles->Count()) == 0" /> - - <Copy - SourceFiles="@(_LayoutFiles)" - DestinationFiles="@(_LayoutFiles->'$(_LayoutPackageRoot)/%(RecursiveDir)%(Filename)%(Extension)')" /> + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishSharedFrameworkToDisk" + Properties="SharedFrameworkOutputPath=$(_LayoutPackageRoot)" + RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> <Copy SourceFiles="@(Manpage)" From 81becff422e42c23a5bc9ab5458a971ad0234d56 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 30 Jul 2020 14:14:19 -0700 Subject: [PATCH 18/46] Better handle GenerateInstallers=false when building linux packages. --- .../targets/installer.targets | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets index 76621696b3a..1fd2db27750 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets @@ -27,8 +27,8 @@ <PropertyGroup> <GenerateDeb>$(GenerateInstallers)</GenerateDeb> <GenerateRpm>$(GenerateInstallers)</GenerateRpm> - <GenerateDeb Condition="'$(BuildDebPackage)' != 'true'">false</GenerateDeb> - <GenerateRpm Condition="'$(BuildRpmPackage)' != 'true'">false</GenerateRpm> + <GenerateDeb Condition="'$(GenerateDeb)' == 'true' and '$(BuildDebPackage)' != 'true'">false</GenerateDeb> + <GenerateRpm Condition="'$(GenerateRpm)' == 'true' and '$(BuildRpmPackage)' != 'true'">false</GenerateRpm> </PropertyGroup> </Target> @@ -41,7 +41,7 @@ <Import Project="$(MSBuildThisFileDirectory)windows/wix.targets" /> - <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipBuild)' != 'true'"> + <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> <ItemGroup> <_InstallerBuildProject Include="$(MSBuildProjectFile)" Targets="GenerateDeb" From 1dd49a18eb66ddcd507d0acea964c3f417d71545 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Fri, 31 Jul 2020 10:33:13 -0700 Subject: [PATCH 19/46] Enable overriding the package id for shared framework packages. --- .../targets/Microsoft.DotNet.SharedFramework.Sdk.targets | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index db2bd229965..657995b31bd 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -81,17 +81,17 @@ Text="Unknown PlatformPackageType '$(PlatformPackageType)'" /> <Error Condition="'$(_PackageTypeRequiresRid)' == 'true' and '$(RuntimeIdentifier)' == ''" Text="Producing a $(PlatformPackageType) requires a runtime-identifier to be specified." /> <PropertyGroup Condition="'$(PlatformPackageType)' == 'TargetingPack'"> - <PackageId>$(SharedFrameworkName).Ref</PackageId> + <PackageId Condition="'$(PackageId)' == ''">$(SharedFrameworkName).Ref</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Ref</SharedFrameworkArchiveName> <MacOSComponentNamePackType>pack.targeting</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> - <PackageId>$(SharedFrameworkName).Runtime.$(RuntimeIdentifier)</PackageId> + <PackageId Condition="'$(PackageId)' == ''">$(SharedFrameworkName).Runtime.$(RuntimeIdentifier)</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Runtime</SharedFrameworkArchiveName> <MacOSComponentNamePackType>sharedframework.$(SharedFrameworkName)</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup Condition="'$(PlatformPackageType)' == 'AppHostPack'"> - <PackageId>$(SharedFrameworkName).Host.$(RuntimeIdentifier)</PackageId> + <PackageId Condition="'$(PackageId)' == ''">$(SharedFrameworkName).Host.$(RuntimeIdentifier)</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Host</SharedFrameworkArchiveName> <MacOSComponentNamePackType>pack.apphost</MacOSComponentNamePackType> </PropertyGroup> From f39a4fc48391fd48ebea0809ad881bf9cbd29ea1 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Fri, 31 Jul 2020 16:53:22 -0700 Subject: [PATCH 20/46] Add OverridePackageId property to avoid colliding with built-in NuGet properties that infer the package id. --- .../Microsoft.DotNet.SharedFramework.Sdk.targets | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 657995b31bd..1f6b47916d9 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -80,23 +80,27 @@ '$(PlatformPackageType)' != 'ToolPack'" Text="Unknown PlatformPackageType '$(PlatformPackageType)'" /> <Error Condition="'$(_PackageTypeRequiresRid)' == 'true' and '$(RuntimeIdentifier)' == ''" Text="Producing a $(PlatformPackageType) requires a runtime-identifier to be specified." /> + <PropertyGroup> + <PackageId Condition="'$(OverridePackageId)' != ''">$(OverridePackageId)</PackageId> + </PropertyGroup> + <PropertyGroup Condition="'$(PlatformPackageType)' == 'TargetingPack'"> - <PackageId Condition="'$(PackageId)' == ''">$(SharedFrameworkName).Ref</PackageId> + <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Ref</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Ref</SharedFrameworkArchiveName> <MacOSComponentNamePackType>pack.targeting</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> - <PackageId Condition="'$(PackageId)' == ''">$(SharedFrameworkName).Runtime.$(RuntimeIdentifier)</PackageId> + <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Runtime.$(RuntimeIdentifier)</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Runtime</SharedFrameworkArchiveName> <MacOSComponentNamePackType>sharedframework.$(SharedFrameworkName)</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup Condition="'$(PlatformPackageType)' == 'AppHostPack'"> - <PackageId Condition="'$(PackageId)' == ''">$(SharedFrameworkName).Host.$(RuntimeIdentifier)</PackageId> + <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Host.$(RuntimeIdentifier)</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Host</SharedFrameworkArchiveName> <MacOSComponentNamePackType>pack.apphost</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup> - <PackageId Condition="'$(PackageId)' == ''">$(SharedFrameworkName)</PackageId> + <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName)</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(PackageId)</SharedFrameworkArchiveName> <MacOSComponentNamePackType Condition="'$(MacOSComponentNamePackType)' == ''">pack.$(PlatformPackageType.ToLower())</MacOSComponentNamePackType> </PropertyGroup> From 3f1708b53ead9f7e1d79090d8e1b321f4fcb314c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Mon, 3 Aug 2020 10:30:13 -0700 Subject: [PATCH 21/46] Fix bad condition for PackageId. --- .../targets/Microsoft.DotNet.SharedFramework.Sdk.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 1f6b47916d9..fa1c6af653a 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -100,7 +100,7 @@ <MacOSComponentNamePackType>pack.apphost</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup> - <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName)</PackageId> + <PackageId Condition="'$(OverridePackageId)' == '' and '$(PackageId)' == ''">$(SharedFrameworkName)</PackageId> <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(PackageId)</SharedFrameworkArchiveName> <MacOSComponentNamePackType Condition="'$(MacOSComponentNamePackType)' == ''">pack.$(PlatformPackageType.ToLower())</MacOSComponentNamePackType> </PropertyGroup> From 50172352c37c9bb6f696561bcdd423788a6fc41d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 4 Aug 2020 18:15:16 -0700 Subject: [PATCH 22/46] First pass moving the installer and bundle infrastructure out of Microsoft.DotNet.SharedFramework.Sdk and into Microsoft.DotNet.Build.Tasks.Installer. --- ...osoft.DotNet.Build.Tasks.Installers.csproj | 2 + ...soft.DotNet.Build.Tasks.Installers.targets | 151 +++++ .../build}/acquisition/Directory.Build.props | 0 .../acquisition/Directory.Build.targets | 0 .../acquire-nuget-exe/acquire-nuget-exe.proj | 0 .../acquisition/acquire-wix/acquire-wix.proj | 0 .../build}/bundle.targets | 12 +- .../package_files/debian/compat | 0 .../package_files/debian/source/format | 0 .../build}/deb-package-tool/package_tool.sh | 0 .../scripts/config_template_generator.py | 0 .../scripts/debian_build_lib.sh | 0 .../scripts/extract_json_value.py | 0 .../scripts/manpage_generator.py | 0 .../deb-package-tool/setup/build_setup.sh | 0 .../deb-package-tool/setup/test_setup.sh | 0 .../templates/debian/changelog | 0 .../deb-package-tool/templates/debian/control | 0 .../templates/debian/copyright | 0 .../deb-package-tool/templates/debian/rules | 0 .../build}/installer.multirid.targets | 2 +- .../build}/installer.props | 0 .../build}/installer.targets | 28 +- .../build}/resources/dotnetbackground.png | Bin .../build}/rpm_templates/changelog | 0 .../build}/rpm_templates/copyright | 0 .../build}/windows/bundle/bundle.wxs | 0 .../build}/windows/bundle/dummyEula.rtf | 0 .../build}/windows/eula.rtf | 0 .../windows/product/breadcrumbstorefolder.wxs | 0 .../build}/windows/product/product.common.wxi | 0 .../build}/windows/product/product.wxs | 0 .../build}/windows/product/provider.wxs | 0 .../build}/windows/product/registrykeys.wxs | 0 .../build}/windows/product/werrelatedkeys.wxs | 0 .../build}/windows/variables.wxi | 0 .../vs/VS.Redist.Common.Component.nuspec.txt | 0 .../build/windows/wix.targets | 538 ++++++++++++++++++ .../src/BuildFPMToolPreReqs.cs | 2 +- .../src/ExecWithRetries.cs | 2 +- .../src/GenerateCurrentVersion.cs | 2 +- .../src/GenerateGuidFromName.cs | 2 +- .../src/GenerateJsonObjectString.cs | 2 +- .../src/GenerateMacOSDistributionFile.cs | 1 - .../src/GenerateMsiVersion.cs | 2 +- .../src/StabilizeWixFileId.cs | 2 +- ...icrosoft.DotNet.SharedFramework.Sdk.csproj | 2 +- .../src/CreateLightCommandPackageDrop.cs | 246 -------- ...crosoft.DotNet.SharedFramework.Sdk.targets | 153 +---- .../targets/archive.props | 2 +- .../targets/archive.targets | 13 +- .../targets/sharedfx.targets | 26 +- .../targets/windows/wix.targets | 530 +---------------- 53 files changed, 775 insertions(+), 945 deletions(-) create mode 100644 src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/acquisition/Directory.Build.props (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/acquisition/Directory.Build.targets (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/acquisition/acquire-wix/acquire-wix.proj (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/bundle.targets (90%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/package_files/debian/compat (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/package_files/debian/source/format (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/package_tool.sh (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/scripts/config_template_generator.py (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/scripts/debian_build_lib.sh (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/scripts/extract_json_value.py (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/scripts/manpage_generator.py (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/setup/build_setup.sh (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/setup/test_setup.sh (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/templates/debian/changelog (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/templates/debian/control (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/templates/debian/copyright (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/deb-package-tool/templates/debian/rules (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/installer.multirid.targets (94%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/installer.props (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/installer.targets (94%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/resources/dotnetbackground.png (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/rpm_templates/changelog (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/rpm_templates/copyright (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/bundle/bundle.wxs (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/bundle/dummyEula.rtf (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/eula.rtf (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/product/breadcrumbstorefolder.wxs (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/product/product.common.wxi (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/product/product.wxs (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/product/provider.wxs (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/product/registrykeys.wxs (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/product/werrelatedkeys.wxs (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/variables.wxi (100%) rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets => Microsoft.DotNet.Build.Tasks.Installers/build}/windows/vs/VS.Redist.Common.Component.nuspec.txt (100%) create mode 100644 src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/BuildFPMToolPreReqs.cs (99%) rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/ExecWithRetries.cs (98%) rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/GenerateCurrentVersion.cs (99%) rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/GenerateGuidFromName.cs (97%) rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/GenerateJsonObjectString.cs (98%) rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/GenerateMacOSDistributionFile.cs (98%) rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/GenerateMsiVersion.cs (98%) rename src/{Microsoft.DotNet.SharedFramework.Sdk => Microsoft.DotNet.Build.Tasks.Installers}/src/StabilizeWixFileId.cs (98%) delete mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj b/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj index 0651857ee47..5d8401ba9f9 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj @@ -14,7 +14,9 @@ <ItemGroup> <PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" /> <PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCoreVersion)" /> + <PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(MicrosoftBuildTasksCoreVersion)" /> <PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkVersion)" /> + <PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" /> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net472'"> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets new file mode 100644 index 00000000000..919b86ebade --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets @@ -0,0 +1,151 @@ +<Project> + <Target Name="_GetCurrentProjectServicingConfiguration"> + <ItemGroup> + <CurrentProjectServicingConfiguration + Include="@(ProjectServicingConfiguration)" + Condition="'%(Identity)' == '$(MSBuildProjectName)'" /> + </ItemGroup> + </Target> + + <!-- + The Microsoft build's per-package servicing policy conflicts with the source-build restrictions. + Targeting packs, for example, are only built/published when there's a known change to release. + This is in contrast to runtime packs and the shared framework, which are always built and + published. This means it's common in the Microsoft build for downstream repos to depend on two + builds' outputs: the current build's runtime assets, and some old build's targeting pack. + + The Microsoft build can simply download the old targeting pack from NuGet.org. Source-build + can't do this because the bits on NuGet.org are not built locally. Instead, source-build assumes + it's possible to use current sources to build a package with the old version. This target + applies the old build's patch version to make that happen. + + This solution has pitfalls. More info at https://github.com/dotnet/core-setup/issues/8735. The + target supports SkipSetLastReleasedVersionForSourceBuild (unused as of writing) to allow + disabling this workaround if a better way forward is implemented. + --> + <Target Name="SetLastReleasedVersionForSourceBuild" + Condition=" + '$(DotNetBuildFromSource)' == 'true' and + '$(SkipSetLastReleasedVersionForSourceBuild)' != 'true'" + BeforeTargets="GetProductVersions" + DependsOnTargets="_GetCurrentProjectServicingConfiguration"> + <PropertyGroup> + <MostRecentProducedServicingPatchVersion>%(CurrentProjectServicingConfiguration.PatchVersion)</MostRecentProducedServicingPatchVersion> + <PatchVersion Condition="'$(MostRecentProducedServicingPatchVersion)' != ''">$(MostRecentProducedServicingPatchVersion)</PatchVersion> + </PropertyGroup> + </Target> + + <Target Name="_GetInstallerSkipBuildProps" + DependsOnTargets=" + _GetCurrentProjectServicingConfiguration; + SetLastReleasedVersionForSourceBuild"> + <!-- + Skip the build if there is an applicable servicing configuration, and the servicing + configuration indicates this project shouldn't build for this patch version. + --> + <PropertyGroup Condition="'@(CurrentProjectServicingConfiguration)' != ''"> + <SkipBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipBuild> + </PropertyGroup> + + <ItemGroup> + <_TargetInstallerRuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> + </ItemGroup> + + <PropertyGroup Condition="'$(InstallerRuntimeIdentifiers)' != '' and '$(InstallerRuntimeIdentifier)' != ''"> + <!-- Avoid building a project when none of the possible InstallerRuntimeIdentifiers is the current InstallerRuntimeIdentifier. --> + <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> + <SkipBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipBuild> + </PropertyGroup> + </Target> + + <PropertyGroup> + <BuildDependsOn>$(BuildDependsOn);_GetInstallerSkipBuildProps</BuildDependsOn> + <_GlobalPropertiesToRemoveForPublish> + GenerateCrossArchMsi; + GenerateMSI; + GeneratePkg; + GenerateDeb; + GenerateRpm; + IsShipping; + ComponentMsiFile; + InstallerRuntimeIdentifier; + InstallerTargetArchitecture; + CrossArchContentsArch + </_GlobalPropertiesToRemoveForPublish> + </PropertyGroup> + + <ItemGroup> + <_GlobalPropertiesToRemoveForPublish Include="$(_GlobalPropertiesToRemoveForPublish)" /> + </ItemGroup> + + <Target Name="_GetTargetOSArchInfo"> + <Error Condition="'$(InstallerRuntimeIdentifier)' == ''" + Text="An InstallerRuntimeIdentifier must be specified when building installers." /> + <PropertyGroup> + <TargetRuntimeOS>$(InstallerRuntimeIdentifier.Substring(0, $(InstallerRuntimeIdentifier.LastIndexOf('-'))))</TargetRuntimeOS> + <TargetArchitecture Condition="'$(TargetArchitecture)' == ''">$(InstallerRuntimeIdentifier.Substring($(InstallerRuntimeIdentifier.LastIndexOf('-'))).TrimStart('-'))</TargetArchitecture> + <InstallerTargetArchitecture Condition="'$(InstallerTargetArchitecture)' == ''">$(TargetArchitecture)</InstallerTargetArchitecture> + </PropertyGroup> + <ItemGroup> + <CrossArchMsiToBuild Include="@(CrossArchSdkMsiInstallerArch)" Exclude="$(TargetArchitecture)" /> + </ItemGroup> + <PropertyGroup> + <_osSupportsWixBasedInstallers Condition="$([MSBuild]::IsOsPlatform(Windows)) and '$(TargetRuntimeOS)' == 'win'">true</_osSupportsWixBasedInstallers> + + <_osArchSupportsWixBasedInstallers>$(_osSupportsWixBasedInstallers)</_osArchSupportsWixBasedInstallers> + <_osArchSupportsWixBasedInstallers Condition="'$(TargetArchitecture)' == 'arm'">false</_osArchSupportsWixBasedInstallers> + </PropertyGroup> + </Target> + + <Target Name="_GetVersionInfo"> + <PropertyGroup> + <IncludePreReleaseLabelInPackageVersion Condition="'$(DotNetFinalVersionKind)' != 'release'">true</IncludePreReleaseLabelInPackageVersion> + <IncludePreReleaseLabelInPackageVersion Condition="'$(SuppressFinalPackageVersion)' == 'true'">true</IncludePreReleaseLabelInPackageVersion> + <IncludePreReleaseLabelInPackageVersion Condition="'$(IsShipping)' != 'true'">true</IncludePreReleaseLabelInPackageVersion> + </PropertyGroup> + </Target> + + <Target Name="_GetProductBrandName" DependsOnTargets="_GetVersionInfo"> + <PropertyGroup + Condition=" + '$(ReleaseBrandSuffix)' == '' and + '$(PreReleaseVersionLabel)' != '' and + '$(PreReleaseVersionIteration)' != ''"> + <!-- Convert 'preview.7' to 'Preview 7'. + 'preview' will come from the pre-release version iteration and the numeric value + will be the PreReleaseVersionIteration. --> + + <ReleaseBrandSuffix>$(PreReleaseVersionLabel.Substring(0,1).ToUpperInvariant())</ReleaseBrandSuffix> + <ReleaseBrandSuffix>$(ReleaseBrandSuffix)$(PreReleaseVersionLabel.Substring(1))</ReleaseBrandSuffix> + <ReleaseBrandSuffix>$(ReleaseBrandSuffix) $(PreReleaseVersionIteration)</ReleaseBrandSuffix> + </PropertyGroup> + + <Error + Text="When building installers a ProductBrandPrefix is required." + Condition="'$(ProductBrandPrefix)' == ''" /> + <Error + Text="When building installers a PackageBrandNameSuffix is required." + Condition="'$(PackageBrandNameSuffix)' == '' and '$(MSBuildProjectExtension)' != '.bundleproj'" /> + <Error + Text="When building a bundle installer, a BundleNameSuffix must be specified." + Condition="'$(BundleNameSuffix)' == '' and '$(MSBuildProjectExtension)' == '.bundleproj'" /> + + <PropertyGroup> + <ProductBrandSuffix>$(VersionPrefix)</ProductBrandSuffix> + <ProductBrandSuffix Condition="'$(ReleaseBrandSuffix)'!=''">$(VersionPrefix) $(ReleaseBrandSuffix)</ProductBrandSuffix> + <ProductBrandName Condition="'$(MSBuildProjectExtension)' == '.bundleproj'">$(ProductBrandPrefix) $(BundleNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> + <ProductBrandName Condition="'$(ProductBrandName)' == ''">$(ProductBrandPrefix) $(PackageBrandNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> + </PropertyGroup> + </Target> + + <PropertyGroup> + <InstallerRuntimeIdentifier Condition="'$(InstallerRuntimeIdentifier)' == ''">$(RuntimeIdentifier)</InstallerRuntimeIdentifier> + </PropertyGroup> + + <Import Project="$(MSBuildThisFileDirectory)installer.targets" + Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' != ''" /> + <Import Project="$(MSBuildThisFileDirectory)installer.multirid.targets" + Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' == ''" /> + <Import Project="$(MSBuildThisFileDirectory)bundle.targets" + Condition="'$(MSBuildProjectExtension)' == '.bundleproj'" /> +</Project> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.props b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.props similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.props rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.props diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/Directory.Build.targets rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-wix/acquire-wix.proj b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/acquire-wix/acquire-wix.proj similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/acquisition/acquire-wix/acquire-wix.proj rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/acquire-wix/acquire-wix.proj diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/bundle.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets similarity index 90% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/bundle.targets rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets index c7806c2f15c..af7d94314b6 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/bundle.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets @@ -39,15 +39,15 @@ DependsOnTargets="_GetTargetOSArchInfo; _GetProductBrandName"> <PropertyGroup> - <SharedFrameworkInstallerName Condition="'$(SharedFrameworkInstallerName)' == ''">$(SharedFrameworkArchiveName)</SharedFrameworkInstallerName> + <InstallerName Condition="'$(InstallerName)' == ''">$(ArchiveName)</InstallerName> </PropertyGroup> <Error - Text="SharedFrameworkInstallerName '$(SharedFrameworkInstallerName)' is empty or starts with a '-': expected a value like 'dotnet-runtime'." - Condition="'$(SharedFrameworkInstallerName)' == '' or $(SharedFrameworkInstallerName.StartsWith('-'))" /> + Text="InstallerName '$(InstallerName)' is empty or starts with a '-': expected a value like 'dotnet-runtime'." + Condition="'$(InstallerName)' == '' or $(InstallerName.StartsWith('-'))" /> <PropertyGroup> - <VersionedInstallerName>$(SharedFrameworkInstallerName)-$(MajorVersion).$(MinorVersion)</VersionedInstallerName> + <VersionedInstallerName>$(InstallerName)-$(MajorVersion).$(MinorVersion)</VersionedInstallerName> <VersionedInstallerName>$(VersionedInstallerName.ToLowerInvariant())</VersionedInstallerName> <InstallerPackageRelease>1</InstallerPackageRelease> <InstallerPackageVersion>$(VersionPrefix)</InstallerPackageVersion> @@ -64,7 +64,7 @@ <InstallerBuildPart>$(Version)-$(TargetRuntimeOS)-$(InstallerTargetArchitecture)</InstallerBuildPart> <!-- Location to place the installer, in artifacts. --> - <InstallerFileNameWithoutExtension>$(SharedFrameworkInstallerName)-$(InstallerBuildPart)</InstallerFileNameWithoutExtension> + <InstallerFileNameWithoutExtension>$(InstallerName)-$(InstallerBuildPart)</InstallerFileNameWithoutExtension> <_InstallerFile Condition="'$(_InstallerFile)' == ''">$(PackageOutputPath)$(InstallerFileNameWithoutExtension)$(InstallerExtension)</_InstallerFile> <ExeBundleInstallerEngineFile>$(PackageOutputPath)$(InstallerFileNameWithoutExtension)-engine.exe</ExeBundleInstallerEngineFile> </PropertyGroup> @@ -105,7 +105,7 @@ <!-- Create macOS pkg installer. --> - <UsingTask TaskName="GenerateMacOSDistributionFile" AssemblyFile="$(DotNetSharedFrameworkTaskFile)"/> + <UsingTask TaskName="GenerateMacOSDistributionFile" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> <Target Name="CreatePkgBundle" DependsOnTargets=" _GetInstallerProperties; diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/compat b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/package_files/debian/compat similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/compat rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/package_files/debian/compat diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/source/format b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/package_files/debian/source/format similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_files/debian/source/format rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/package_files/debian/source/format diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_tool.sh b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/package_tool.sh similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/package_tool.sh rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/package_tool.sh diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/config_template_generator.py b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/config_template_generator.py similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/config_template_generator.py rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/config_template_generator.py diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/debian_build_lib.sh b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/debian_build_lib.sh similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/debian_build_lib.sh rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/debian_build_lib.sh diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/extract_json_value.py b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/extract_json_value.py similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/extract_json_value.py rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/extract_json_value.py diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/manpage_generator.py b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/manpage_generator.py similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/scripts/manpage_generator.py rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/scripts/manpage_generator.py diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/build_setup.sh b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/setup/build_setup.sh similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/build_setup.sh rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/setup/build_setup.sh diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/test_setup.sh b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/setup/test_setup.sh similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/setup/test_setup.sh rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/setup/test_setup.sh diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/changelog b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/changelog similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/changelog rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/changelog diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/control b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/control similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/control rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/control diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/copyright b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/copyright similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/copyright rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/copyright diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/rules b/src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/rules similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/deb-package-tool/templates/debian/rules rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/deb-package-tool/templates/debian/rules diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.multirid.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.multirid.targets similarity index 94% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.multirid.targets rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.multirid.targets index 59fc23d142f..191fcbe78d9 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.multirid.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.multirid.targets @@ -12,7 +12,7 @@ <Target Name="GenerateInstallers" Condition="'$(SkipBuild)' != 'true'" - DependsOnTargets="_GetSkipBuildProps;_ComputeInstallerItems" + DependsOnTargets="_GetInstallerSkipBuildProps;_ComputeInstallerItems" Returns="@(InnerOutput)"> <Error Condition="'$(InstallerRuntimeIdentifiers)' == ''" Text="At least one RID must be specified via InstallerRuntimeIdentifiers to build installers." /> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.props b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.props similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.props rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.props diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets similarity index 94% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets index 1fd2db27750..be66c83335d 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/installer.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets @@ -36,8 +36,8 @@ Shared targets to build installers and distro packages. --> - <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(DotNetSharedFrameworkTaskFile)"/> - <UsingTask TaskName="GenerateJsonObjectString" AssemblyFile="$(DotNetSharedFrameworkTaskFile)"/> + <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> + <UsingTask TaskName="GenerateJsonObjectString" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> <Import Project="$(MSBuildThisFileDirectory)windows/wix.targets" /> @@ -88,16 +88,16 @@ _GetTargetOSArchInfo; _GetProductBrandName"> <PropertyGroup> - <SharedFrameworkInstallerName Condition="'$(SharedFrameworkInstallerName)' == ''">$(SharedFrameworkArchiveName)</SharedFrameworkInstallerName> + <InstallerName Condition="'$(InstallerName)' == ''">$(ArchiveName)</InstallerName> </PropertyGroup> <Error - Text="SharedFrameworkInstallerName '$(SharedFrameworkInstallerName)' is empty or starts with a '-': expected a value like 'dotnet-runtime'." - Condition="'$(SharedFrameworkInstallerName)' == '' or $(SharedFrameworkInstallerName.StartsWith('-'))" /> + Text="InstallerName '$(InstallerName)' is empty or starts with a '-': expected a value like 'dotnet-runtime'." + Condition="'$(InstallerName)' == '' or $(InstallerName.StartsWith('-'))" /> <PropertyGroup> - <VersionedInstallerName Condition="'$(VersionInstallerName)' == 'true'">$(SharedFrameworkInstallerName)-$(MajorVersion).$(MinorVersion)</VersionedInstallerName> - <VersionedInstallerName Condition="'$(VersionInstallerName)' != 'true'">$(SharedFrameworkInstallerName)</VersionedInstallerName> + <VersionedInstallerName Condition="'$(VersionInstallerName)' == 'true'">$(InstallerName)-$(MajorVersion).$(MinorVersion)</VersionedInstallerName> + <VersionedInstallerName Condition="'$(VersionInstallerName)' != 'true'">$(InstallerName)</VersionedInstallerName> <VersionedInstallerName>$(VersionedInstallerName.ToLowerInvariant())</VersionedInstallerName> <InstallerPackageRelease>1</InstallerPackageRelease> <InstallerPackageVersion>$(VersionPrefix)</InstallerPackageVersion> @@ -137,7 +137,7 @@ </PropertyGroup> <PropertyGroup> <!-- Location to place the installer, in artifacts. --> - <InstallerFileNameWithoutExtension>$(SharedFrameworkInstallerName)-$(InstallerBuildPart)$(CrossArchContentsBuildPart)</InstallerFileNameWithoutExtension> + <InstallerFileNameWithoutExtension>$(InstallerName)-$(InstallerBuildPart)$(CrossArchContentsBuildPart)</InstallerFileNameWithoutExtension> <_InstallerFile Condition="'$(_InstallerFile)' == ''">$(PackageOutputPath)$(InstallerFileNameWithoutExtension)$(InstallerExtension)</_InstallerFile> <ExeBundleInstallerFile>$(PackageOutputPath)$(InstallerFileNameWithoutExtension).exe</ExeBundleInstallerFile> <ExeBundleInstallerEngineFile>$(PackageOutputPath)$(InstallerFileNameWithoutExtension)-engine.exe</ExeBundleInstallerEngineFile> @@ -364,12 +364,12 @@ <!-- Copy files to layout. --> <PropertyGroup> - <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/</_SharedFrameworkOutputPathRoot> + <_OutputPathRoot>$(IntermediateOutputPath)/output</_OutputPathRoot> </PropertyGroup> <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkToDisk" - Properties="SharedFrameworkOutputPath=$(_SharedFrameworkOutputPathRoot)" + Targets="PublishToDisk" + Properties="OutputPath=$(_OutputPathRoot)" RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> <PropertyGroup> <_MacOSVersionComponent Condition="'$(IncludeVersionInMacOSComponentName)' == 'true'">.$(ProductVersion)</_MacOSVersionComponent> @@ -377,7 +377,7 @@ <_MacOSSharedInstallDir>/usr/local/share/dotnet</_MacOSSharedInstallDir> <_pkgArgs></_pkgArgs> - <_pkgArgs>$(_pkgArgs) --root $(_SharedFrameworkOutputPathRoot)</_pkgArgs> + <_pkgArgs>$(_pkgArgs) --root $(_OutputPathRoot)</_pkgArgs> <_pkgArgs>$(_pkgArgs) --identifier $(_MacOSComponentName)</_pkgArgs> <_pkgArgs>$(_pkgArgs) --version $(ProductVersion)</_pkgArgs> <_pkgArgs>$(_pkgArgs) --install-location $(_MacOSSharedInstallDir)</_pkgArgs> @@ -417,8 +417,8 @@ <MakeDir Directories="$(_LayoutDocs)" /> <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkToDisk" - Properties="SharedFrameworkOutputPath=$(_LayoutPackageRoot)" + Targets="PublishToDisk" + Properties="OutputPath=$(_LayoutPackageRoot)" RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> <Copy diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/resources/dotnetbackground.png b/src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/dotnetbackground.png similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/resources/dotnetbackground.png rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/dotnetbackground.png diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/changelog b/src/Microsoft.DotNet.Build.Tasks.Installers/build/rpm_templates/changelog similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/changelog rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/rpm_templates/changelog diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/copyright b/src/Microsoft.DotNet.Build.Tasks.Installers/build/rpm_templates/copyright similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/rpm_templates/copyright rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/rpm_templates/copyright diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/bundle.wxs similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/bundle.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/bundle.wxs diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/dummyEula.rtf b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/dummyEula.rtf similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/bundle/dummyEula.rtf rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/dummyEula.rtf diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/eula.rtf b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/eula.rtf similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/eula.rtf rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/eula.rtf diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/breadcrumbstorefolder.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/breadcrumbstorefolder.wxs similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/breadcrumbstorefolder.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/breadcrumbstorefolder.wxs diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.common.wxi similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.common.wxi rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.common.wxi diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.wxs similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/product.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.wxs diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/provider.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/provider.wxs similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/provider.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/provider.wxs diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/registrykeys.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/registrykeys.wxs similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/registrykeys.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/registrykeys.wxs diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/werrelatedkeys.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/werrelatedkeys.wxs similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/werrelatedkeys.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/werrelatedkeys.wxs diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/variables.wxi similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/variables.wxi rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/variables.wxi diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/vs/VS.Redist.Common.Component.nuspec.txt b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/vs/VS.Redist.Common.Component.nuspec.txt similarity index 100% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/vs/VS.Redist.Common.Component.nuspec.txt rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/vs/VS.Redist.Common.Component.nuspec.txt diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets new file mode 100644 index 00000000000..6b66b32bda4 --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets @@ -0,0 +1,538 @@ +<Project> + <!-- + These targets use MSBuild Exec tasks to run WiX 3 toolset commands. + + WiX 4 is expected to support running in .NET Core. Once using WiX 4, we can (more easily) remove + this file and switch to wixproj. See https://github.com/wixtoolset/issues/issues/5627 + --> + + <UsingTask TaskName="CreateLightCommandPackageDrop" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="ExecWithRetries" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateCurrentVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateGuidFromName" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + + <!-- + Acquire WiX tools, if not present. + --> + <Target Name="AcquireWix" + DependsOnTargets="GetAcquireWixProperties"> + <MSBuild + Projects="$(AcquireWixProjectFile)" + Targets="AcquireWixCore" + Properties="BaseIntermediateOutputPath=$(BaseIntermediateOutputPath); + RepoRoot=$(RepoRoot)" /> + </Target> + + <Target Name="GetAcquireWixProperties"> + + <PropertyGroup> + <_WixIntermediateOutputPath>$(BaseIntermediateOutputPath)wix</_WixIntermediateOutputPath> + </PropertyGroup> + + <PropertyGroup> + <WixVersion>3.14.0.4118</WixVersion> + <WixToolsDir>$(BaseIntermediateOutputPath)WixTools.$(WixVersion)/</WixToolsDir> + <!-- Used in WiX targets to locate files. --> + <WixInstallPath>$(WixToolsDir)</WixInstallPath> + <WixTargetsPath>$(WixToolsDir)wix.targets</WixTargetsPath> + <WixObjDir>$(IntermediateOutputPath)/wix/</WixObjDir> + <WixObjDir Condition="'$(RuntimeIdentifier)' == ''">$(IntermediateOutputPath)/$(InstallerRuntimeIdentifier)/wix/</WixObjDir> + <LightCommandObjDir>$(IntermediateOutputPath)/lightcommand/</LightCommandObjDir> + <MsiArch>$(InstallerTargetArchitecture)</MsiArch> + + <AcquireWixProjectFile>$(MSBuildThisFileDirectory)..\acquisition\acquire-wix\acquire-wix.proj</AcquireWixProjectFile> + <WixDownloadFilename>wix.$(WixVersion).zip</WixDownloadFilename> + <WixDownloadUrl>https://dotnetcli.azureedge.net/build/wix/$(WixDownloadFilename)</WixDownloadUrl> + <WixDestinationPath>$(WixToolsDir)$(WixDownloadFilename)</WixDestinationPath> + <WixDownloadSentinel>$(WixToolsDir)WixDownload.$(WixVersion).sentinel</WixDownloadSentinel> + </PropertyGroup> + </Target> + + <Target Name="_GenerateMsiVersionString"> + <PropertyGroup> + <VersionPadding Condition="'$(VersionPadding)'==''">5</VersionPadding> + <!-- Using the following default comparison date will produce versions that align with our internal build system. --> + <VersionComparisonDate Condition="'$(VersionComparisonDate)'==''">1996-04-01</VersionComparisonDate> + </PropertyGroup> + + <GenerateCurrentVersion + SeedDate="$([System.DateTime]::Now.ToString(yyyy-MM-dd))" + OfficialBuildId="$(OfficialBuildId)" + ComparisonDate="$(VersionComparisonDate)" + Padding="$(VersionPadding)"> + <Output PropertyName="BuildNumberMajor" TaskParameter="GeneratedVersion" /> + <Output PropertyName="BuildNumberMinor" TaskParameter="GeneratedRevision" /> + </GenerateCurrentVersion> + + <GenerateMsiVersion + Major="$(MajorVersion)" + Minor="$(MinorVersion)" + Patch="$(PatchVersion)" + BuildNumberMajor="$(BuildNumberMajor)" + BuildNumberMinor="$(BuildNumberMajor)"> + <Output TaskParameter="MsiVersion" PropertyName="MsiVersionString" /> + </GenerateMsiVersion> + </Target> + + <!-- + Generate bundle upgrade code. This code needs to be constant within a product band for upgrades. + --> + <Target Name="GetBundleUpgradeCode" + DependsOnTargets="GetWixBuildConfiguration" + Condition=" + '$(GenerateExeBundle)' == 'true' and + '$(UpgradeCode)' == ''"> + <Error + Condition="'$(BundleInstallerUpgradeCodeSeed)' == ''" + Text="BundleInstallerUpgradeCodeSeed not defined. Required to produce a stable bundle upgrade code." /> + + <PropertyGroup> + <BundleInstallerOutputGuidString>$(BundleInstallerUpgradeCodeSeed) $(MajorVersion).$(MinorVersion) $(RuntimeIdentifier)</BundleInstallerOutputGuidString> + </PropertyGroup> + + <GenerateGuidFromName Name="$(BundleInstallerOutputGuidString)"> + <Output TaskParameter="GeneratedGuid" PropertyName="UpgradeCode" /> + </GenerateGuidFromName> + </Target> + + <!-- + If UpgradeCode isn't already set, generate one based on installer full path. + --> + <Target Name="_GetUpgradeCode" + DependsOnTargets="GetWixBuildConfiguration" + Condition="'$(UpgradeCode)' == ''"> + <GenerateGuidFromName Name="$(_OutInstallerFile)"> + <Output TaskParameter="GeneratedGuid" PropertyName="UpgradeCode" /> + </GenerateGuidFromName> + </Target> + + <Target Name="_UseProductWixProject"> + <ItemGroup> + <WixExtensions Include="WixUIExtension.dll" /> + <WixExtensions Include="WixDependencyExtension.dll" /> + <WixExtensions Include="WixUtilExtension.dll" /> + + <WixSrcFile Include="$(MSBuildThisFileDirectory)product/product.wxs" /> + <WixSrcFile Include="$(MSBuildThisFileDirectory)product/provider.wxs" /> + </ItemGroup> + </Target> + + <Target Name="UseBundleWixProject"> + <ItemGroup> + <WixExtensions Include="WixBalExtension.dll" /> + <WixExtensions Include="WixTagExtension.dll" /> + <WixExtensions Include="WixUtilExtension.dll" /> + + <WixSrcFile Include="$(MSBuildThisFileDirectory)bundle/bundle.wxs" /> + </ItemGroup> + </Target> + + <Target Name="PublishFilesForWixInstaller"> + <PropertyGroup> + <FilesOutputPathRoot>$(IntermediateOutputPath)/output</FilesOutputPathRoot> + </PropertyGroup> + + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishToDisk" + Properties="OutputPath=$(FilesOutputPathRoot)" + RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> + </Target> + + <Target Name="GetInstallerWixConfiguration" + DependsOnTargets="_UseProductWixProject;PublishFilesForWixInstaller" + Condition="'$(GenerateExeBundle)' != 'true'"> + + <PropertyGroup> + <OutputFilesCandleVariable Condition="'$(OutputFilesCandleVariable)' == ''">PackSrc</OutputFilesCandleVariable> + </PropertyGroup> + + <ItemGroup Condition="'$(UseCustomDirectoryHarvesting)' != 'true'"> + <DirectoryToHarvest + Include="$(FilesOutputPathRoot)" + Condition="'$(UseCustomDirectoryHarvesting)' != 'true'" + Name="install-files" + SubstituteVar="$(OutputFilesCandleVariable)" + ComponentGroupName="InstallFiles" + DirectoryRef="DOTNETHOME" /> + <CandleVariables Include="$(OutputFilesCandleVariable)" Value="$(FilesOutputPathRoot)" + Condition="'$(UseCustomDirectoryHarvesting)' == 'true'" /> + </ItemGroup> + + <ItemGroup Condition="$(IncludeWerRelatedKeys)' == 'true'"> + <WixSrcFile Include="$(MSBuildThisFileDirectory)product/werrelatedkeys.wxs" /> + <CandleVariables Include="WerRelatedKeys" Value="true" /> + </ItemGroup> + + <ItemGroup Condition="'$(IncludeBreadcrumbStoreFolder)' == 'true'"> + <WixSrcFile Include="$(MSBuildThisFileDirectory)product/breadcrumbstorefolder.wxs" /> + <CandleVariables Include="BreadcrumbStoreFolder" Value="true" /> + </ItemGroup> + + <ItemGroup Condition="'$(WixIncludeRegistryKeys)' == 'true'"> + <WixSrcFile Include="$(MSBuildThisFileDirectory)product/registrykeys.wxs" /> + </ItemGroup> + </Target> + + <Target Name="GetBundleWixConfiguration" + Condition="'$(GenerateExeBundle)' == 'true'" + DependsOnTargets=" + UseBundleWixProject; + GetBundledMsiFiles"> + <Error Text="A bundle theme directory property must be specified with the BundleThemeDirectory property." + Condition="'$(BundleThemeDirectory)' == ''" /> + + <ItemGroup> + <LocFile Include="$(BundleThemeDirectory)\theme\**\bundle.wxl" /> + <LocDirName Include="$([System.String]::new('%(LocFile.RecursiveDir)').TrimEnd('\'))" /> + + <CandleVariables Include="DisplayVersion" Value="$(MajorVersion).$(MinorVersion).$(PatchVersion).$(BuildNumberMajor)" /> + <CandleVariables Include="ProductBandVersion" Value="$(MajorVersion).$(MinorVersion)" /> + <CandleVariables Include="FrameworkDisplayVersion" Value="$(ProductVersion)" /> + <CandleVariables Include="LcidList" Value="@(LocDirName)" /> + <CandleVariables Include="BundleThmDir" Value="$(BundleThemeDirectory)" /> + + <CandleVariables Include="DotNetBackgroundPngFile" Value="$(MSBuildThisFileDirectory)..\resources\dotnetbackground.png" /> + <CandleVariables Include="DotNetDummyEulaFile" Value="$(MSBuildThisFileDirectory)bundle\dummyEula.rtf" /> + </ItemGroup> + + <PropertyGroup> + <_OutInstallerFile>$(_InstallerFile)</_OutInstallerFile> + </PropertyGroup> + </Target> + + <!-- Set up information to pass to WiX, depending on the type of installer being created. --> + <Target Name="GetWixBuildConfiguration" + DependsOnTargets=" + AcquireWix; + _GetInstallerProperties; + _GenerateMsiVersionString; + GetInstallerWixConfiguration; + GetBundleWixConfiguration"> + <PropertyGroup> + <_OutInstallerFile Condition="'$(_OutInstallerFile)' == ''">$(_InstallerFile)</_OutInstallerFile> + </PropertyGroup> + <PropertyGroup> + <!-- + Native arm64 MSI packages require version 500 of MSI database schema, see: + https://docs.microsoft.com/en-us/windows/win32/msi/using-64-bit-windows-installer-packages + --> + <WixInstallerVersion Condition="'$(WixInstallerVersion)' == '' and '$(MsiArch)' == 'arm64'">500</WixInstallerVersion> + <WixInstallerVersion Condition="'$(WixInstallerVersion)' == ''">200</WixInstallerVersion> + </PropertyGroup> + + <ItemGroup> + <CandleVariables Include="MicrosoftEula" Value="$(MSBuildThisFileDirectory)eula.rtf" /> + <CandleVariables Include="InstallerVersion" Value="$(WixInstallerVersion)" /> + </ItemGroup> + </Target> + + <!-- + Ensure MSIs are built and signed (if necessary), then obtain all paths to MSIs to bundle from + the bundle references. + --> + <Target Name="GetBundledMsiFiles" DependsOnTargets="_GetBundledComponentInstallers"> + <ItemGroup> + <CandleVariables Include="ChainedDotNetPackageFiles" Value="@(_BundledComponents)" /> + </ItemGroup> + </Target> + + <Target Name="RunHeatHarvester" + Condition="'@(DirectoryToHarvest)' != ''" + DependsOnTargets="GetWixBuildConfiguration"> + <ItemGroup> + <DirectoryToHarvest + WixSourceFile="$(WixObjDir)%(Name).wxs" + WixObjFile="$(WixObjDir)%(Name).wixobj" /> + + <DirectoryToHarvest + Command="heat.exe ^ + dir "%(Identity)" ^ + -nologo ^ + -template fragment ^ + -sreg ^ + -ag ^ + -var var.%(SubstituteVar) ^ + -cg %(ComponentGroupName) ^ + -srd ^ + -dr %(DirectoryRef) ^ + -out %(WixSourceFile)" /> + + <CandleVariables Include="InstallFiles" Value="true" /> + </ItemGroup> + + <Exec + Command="%(DirectoryToHarvest.Command)" + WorkingDirectory="$(WixToolsDir)" + StandardOutputImportance="normal" /> + + <!-- + Currently FileElementToStabilize assumes a single DirectoryToHarvest. If there were multiple, + the task would expect exactly one match in each file, which isn't likely to be the case. But, + there is no known scenario to have multiple DirectoryToHarvest and use FileElementToStabilize. + --> + <StabilizeWixFileId + Condition="'@(HeatOutputFileElementToStabilize)' != ''" + SourceFile="%(DirectoryToHarvest.WixSourceFile)" + OutputFile="%(DirectoryToHarvest.WixSourceFile)" + FileElementToStabilize="@(HeatOutputFileElementToStabilize)" /> + </Target> + + <Target Name="RunCandleCompiler" + DependsOnTargets=" + GetWixBuildConfiguration; + GetBundleUpgradeCode; + _GetUpgradeCode; + _GenerateMsiVersionString"> + <PropertyGroup> + <WixDependencyKeyName Condition="'$(WixDependencyKeyName)' == ''">$(InstallerName.Replace('-', '_'))</WixDependencyKeyName> + </PropertyGroup> + + <ItemGroup> + <CandleVariables Include="SharedWixDir" Value="$(MSBuildThisFileDirectory.TrimEnd('\'))" /> + <CandleVariables Include="DependencyKeyName" Value="$(WixDependencyKeyName)" /> + + <CandleVariables Include="%(DirectoryToHarvest.SubstituteVar)" Value="%(DirectoryToHarvest.Identity)" /> + + <CandleVariables Include="ExtraComponentGroupRefIds" Value="@(WixExtraComponentGroupRefId)" Condition="'@(WixExtraComponentGroupRefId)' != ''" /> + <CandleVariables Include="RegKeyProductName" Value="$(RegKeyProductName)" Condition="'$(RegKeyProductName)' != ''" /> + + <CandleVariables Include="ProductMoniker" Value="$(ProductBrandName)" /> + <CandleVariables Include="BuildVersion" Value="$(MsiVersionString)" /> + <CandleVariables Include="NugetVersion" Value="$(Version)" /> + <CandleVariables Include="TargetArchitectureDescription" Value="$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart)" /> + <CandleVariables Include="UpgradeCode" Value="$(UpgradeCode)" /> + + <!-- If this is a cross-arch MSI, add target arch to the dependency key for uniqueness. --> + <CandleVariables Include="CrossArchContentsPlatformPart" Value="$(CrossArchContentsBuildPart.Replace('-', '_'))" /> + </ItemGroup> + + <PropertyGroup> + <_wixArgs></_wixArgs> + <_wixArgs>$(_wixArgs) -nologo</_wixArgs> + <_wixArgs>$(_wixArgs) -arch $(MsiArch)</_wixArgs> + <_wixArgs>$(_wixArgs) -out "$(WixObjDir)"</_wixArgs> + + <_wixArgs>$(_wixArgs) @(WixExtensions -> '-ext %(Identity)', ' ')</_wixArgs> + <_wixArgs>$(_wixArgs) @(CandleVariables -> '-d%(Identity)="%(Value)"', ' ')</_wixArgs> + <_wixArgs>$(_wixArgs) @(WixSrcFile -> '"%(FullPath)"', ' ')</_wixArgs> + <_wixArgs>$(_wixArgs) @(DirectoryToHarvest -> '"%(WixSourceFile)"', ' ')</_wixArgs> + </PropertyGroup> + + <Exec + Command="candle.exe $(_wixArgs)" + WorkingDirectory="$(WixToolsDir)" + StandardOutputImportance="normal" /> + </Target> + + <Target Name="RunLightLinker" + DependsOnTargets=" + GetWixBuildConfiguration; + RunHeatHarvester; + RunCandleCompiler"> + <PropertyGroup> + <_wixArgs></_wixArgs> + <_wixArgs>$(_wixArgs) -nologo</_wixArgs> + <_wixArgs>$(_wixArgs) -cultures:en-us</_wixArgs> + <_wixArgs>$(_wixArgs) -out $(_OutInstallerFile)</_wixArgs> + + <_wixArgs>$(_wixArgs) @(WixExtensions -> '-ext %(Identity)', ' ')</_wixArgs> + <_wixArgs>$(_wixArgs) @(WixSrcFile -> '"$(WixObjDir)%(Filename).wixobj"', ' ')</_wixArgs> + <_wixArgs>$(_wixArgs) @(DirectoryToHarvest -> '"%(WixObjFile)"', ' ')</_wixArgs> + <_lightCommand>light.exe $(_wixArgs)</_lightCommand> + + <_LightCommandPackagesDir>$(ArtifactsNonShippingPackagesDir)</_LightCommandPackagesDir> + </PropertyGroup> + + <!-- + Run light.exe with retries. This hardens against interference by Windows Defender by giving + Defender time to catch up. Light creates a file then immediately moves it, which fails when + Defender is holding it open. Uses a small base time because it resolves itself quickly and we + don't want to delay the build very long if it's an actual build authoring error. + --> + <ExecWithRetries + Command="$(_lightCommand)" + WorkingDirectory="$(WixToolsDir)" + StandardOutputImportance="normal" + IgnoreStandardErrorWarningFormat="true" + RetryDelayBase="2" /> + + <CreateLightCommandPackageDrop + OriginalLightCommand="$(_lightCommand)" + LightCommandWorkingDir="$(LightCommandObjDir)" + NoLogo="true" + Cultures="en-us" + Out="$(_OutInstallerFile)" + WixExtensions="@(WixExtensions)" + WixSrcFiles="@(WixSrcFile -> '$(WixObjDir)%(Filename).wixobj');@(DirectoryToHarvest -> '%(WixObjFile)')"> + <Output TaskParameter="LightCommandPackageNameOutput" PropertyName="_LightCommandPackageNameOutput" /> + </CreateLightCommandPackageDrop> + + <MakeDir Directories="$(_LightCommandPackagesDir)" /> + + <ZipDirectory + DestinationFile="$(_LightCommandPackagesDir)/LightCommandPackage-$(_LightCommandPackageNameOutput).zip" + Overwrite="true" + SourceDirectory="$(LightCommandObjDir)/$(_LightCommandPackageNameOutput)" /> + </Target> + + <!-- + Entry point for an MSBuild call: creates NuGet packages suitable for VS insertion. + --> + <Target Name="GenerateVSInsertionNupkg" + DependsOnTargets=" + GetInstallerGenerationFlags; + GenerateCurrentArchVSInsertionNupkg; + GenerateCrossArchVSInsertionNupkg" /> + + <Target Name="GenerateCurrentArchVSInsertionNupkg" + Condition="'$(GenerateMSI)' == 'true'"> + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="CreateWixInstaller" + Properties="GenerateMSI=true" + RemoveProperties="GenerateCrossArchMsi"> + <Output TaskParameter="TargetOutputs" PropertyName="_ComponentMsiFile" /> + + </MSBuild> + + <!-- + Run the nupkg creation code with IsShipping=false to use prerelease versions: this package + must not be stable to avoid mutation conflicts, even though the project itself may be shipping + and therefore stabilized. + + Also pass in the path to the MSI file to pack up because its file name is based on + stabilization status. + --> + <MSBuild + Projects="$(MSBuildProjectFullPath)" + Targets="GenerateVSInsertionNupkgCore" + Properties=" + IsShipping=false; + ComponentMsiFile=$(_ComponentMsiFile)" /> + </Target> + + <Target Name="GenerateCrossArchVSInsertionNupkg" + Condition="'$(GenerateCrossArchMsi)' == 'true'" + DependsOnTargets=" + _GetInstallerProperties; + GenerateCrossArchVSInsertionNupkgPerArch" /> + + <Target Name="GenerateCrossArchVSInsertionNupkgPerArch" + Condition="'@(CrossArchMsiToBuild)' != ''" + Inputs="%(CrossArchMsiToBuild.Identity)" + Outputs="batching-on-CrossArchMsiToBuild"> + <!-- + Get the cross-arch MSI to pack into an insertion package. Do this separately from the + GenerateVSInsertionNupkgCore call because IsShipping influences the file name. + --> + <MSBuild + Projects="$(MSBuildProjectFullPath)" + Targets="CreateCrossArchWixInstaller" + Properties=" + GenerateCrossArchMsi=true; + InstallerTargetArchitecture=%(CrossArchMsiToBuild.Identity); + CrossArchContentsArch=$(TargetArchitecture)" + RemoveProperties="GenerateMSI"> + <Output TaskParameter="TargetOutputs" PropertyName="CrossArchMsiFile" /> + </MSBuild> + + <MSBuild + Projects="$(MSBuildProjectFullPath)" + Targets="GenerateVSInsertionNupkgCore" + Properties=" + InstallerTargetArchitecture=%(CrossArchMsiToBuild.Identity); + CrossArchContentsArch=$(TargetArchitecture); + IsShipping=false; + ComponentMsiFile=$(CrossArchMsiFile)" /> + </Target> + + <!-- + Acquire NuGet.exe, if not present. + --> + <Target Name="_AcquireNuGetExe" + DependsOnTargets="_GetAcquireNuGetExeProperties"> + <MSBuild + Projects="$(AcquireNuGetExeProjectFile)" + Targets="AcquireNuGetExeCore" + Properties="BaseIntermediateOutputPath=$(BaseIntermediateOutputPath); + RepoRoot=$(RepoRoot)" /> + </Target> + + <Target Name="_GetAcquireNuGetExeProperties"> + <PropertyGroup> + <AcquireNuGetExeProjectFile>$(MSBuildThisFileDirectory)..\acquisition\acquire-nuget-exe\acquire-nuget-exe.proj</AcquireNuGetExeProjectFile> + <!-- Using 3.5.0 to workaround https://github.com/NuGet/Home/issues/5016 --> + <NuGetExeDownloadUrl>https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe</NuGetExeDownloadUrl> + <NuGetExeToolDir>$(BaseIntermediateOutputPath)nuget\</NuGetExeToolDir> + <NuGetExeFile>$(NuGetExeToolDir)NuGet.exe</NuGetExeFile> + </PropertyGroup> + </Target> + + <Target Name="GenerateVSInsertionNupkgCore" + DependsOnTargets=" + _GetTargetOSArchInfo; + GetAcquireWixProperties; + _AcquireNuGetExe; + _GetInstallerProperties; + GetWixBuildConfiguration"> + <PropertyGroup> + <VSInsertionComponentName>VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion)</VSInsertionComponentName> + <NupkgOutputFile>$(ArtifactsNonShippingPackagesDir)$(VSInsertionComponentName).$(Version).nupkg</NupkgOutputFile> + + <!-- Work around NuGet silently ignoring nuspec files in PackTask by changing extension. https://github.com/NuGet/Home/issues/8637 --> + <MangledNuspecFile>$(MSBuildThisFileDirectory)vs\VS.Redist.Common.Component.nuspec.txt</MangledNuspecFile> + <VsInsertionNuspecFile>$(IntermediateOutputPath)vs\VS.Redist.Common.Component.nuspec</VsInsertionNuspecFile> + + <PackProperties /> + <PackProperties>$(PackProperties)COMPONENT_MSI=$(ComponentMsiFile);</PackProperties> + <PackProperties>$(PackProperties)ARCH=$(MsiArch);</PackProperties> + <PackProperties>$(PackProperties)COMPONENT_NAME=$(VSInsertionComponentName);</PackProperties> + <PackProperties>$(PackProperties)FRIENDLY_NAME=$(ProductBrandName);</PackProperties> + <PackProperties>$(PackProperties)PROJECT_URL=$(RepositoryUrl);</PackProperties> + + <PackArgs /> + <PackArgs>$(PackArgs) $(VsInsertionNuspecFile)</PackArgs> + <PackArgs>$(PackArgs) -Version $(Version)</PackArgs> + <PackArgs>$(PackArgs) -OutputDirectory $(ArtifactsNonShippingPackagesDir)</PackArgs> + <PackArgs>$(PackArgs) -NoDefaultExcludes</PackArgs> + <PackArgs>$(PackArgs) -NoPackageAnalysis</PackArgs> + <PackArgs>$(PackArgs) -Properties "$(PackProperties)"</PackArgs> + </PropertyGroup> + + <Copy SourceFiles="$(MangledNuspecFile)" DestinationFiles="$(VsInsertionNuspecFile)" /> + + <Exec Command="$(NuGetExeFile) pack $(PackArgs)" StandardOutputImportance="normal" /> + + <Error + Condition="!Exists('$(NupkgOutputFile)')" + Text="Failed to find VS insertion nupkg after pack command. Expected '$(NupkgOutputFile)'" /> + + <Message Text="$(MSBuildProjectName) -> $(NupkgOutputFile)" Importance="High" /> + </Target> + + <Target Name="ExtractEngineBundle" + DependsOnTargets=" + GetInstallerGenerationFlags; + GetWixBuildConfiguration"> + <Exec + Condition="'$(GenerateExeBundle)' == 'true'" + Command="insignia.exe -ib $(_OutInstallerFile) -o $(ExeBundleInstallerEngineFile)" + WorkingDirectory="$(WixToolsDir)" /> + </Target> + + <Target Name="ReattachEngineToBundle" + DependsOnTargets=" + GetInstallerGenerationFlags; + GetWixBuildConfiguration"> + <Exec + Condition="'$(GenerateExeBundle)' == 'true'" + Command="insignia.exe -ab $(ExeBundleInstallerEngineFile) $(_OutInstallerFile) -o $(_OutInstallerFile)" + WorkingDirectory="$(WixToolsDir)" /> + </Target> + + <Target Name="GetOutputWixInstallerFile" + DependsOnTargets="GetWixBuildConfiguration" + Returns="$(_OutInstallerFile)"/> + +</Project> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/BuildFPMToolPreReqs.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/BuildFPMToolPreReqs.cs similarity index 99% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/BuildFPMToolPreReqs.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/BuildFPMToolPreReqs.cs index f6b519593f6..c956a24e661 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/BuildFPMToolPreReqs.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/BuildFPMToolPreReqs.cs @@ -11,7 +11,7 @@ using System.Linq; using System.Text; -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +namespace Microsoft.DotNet.Build.Tasks.Installers { /// <summary> /// This task prepares the command line parameters for running a RPM build using FPM tool and also updates the copyright and changelog file tokens. diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/ExecWithRetries.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/ExecWithRetries.cs similarity index 98% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/ExecWithRetries.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/ExecWithRetries.cs index 5aeb1d3bd37..3beaa96ec29 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/ExecWithRetries.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/ExecWithRetries.cs @@ -10,7 +10,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +namespace Microsoft.DotNet.Build.Tasks.Installers { /// <summary> /// Run a command and retry if the exit code is not 0. diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateCurrentVersion.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateCurrentVersion.cs similarity index 99% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateCurrentVersion.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateCurrentVersion.cs index 281b2be1130..3c00c3a5f83 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateCurrentVersion.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateCurrentVersion.cs @@ -7,7 +7,7 @@ using System.Globalization; using System.Text.RegularExpressions; -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +namespace Microsoft.DotNet.Build.Tasks.Installers { public sealed class GenerateCurrentVersion : BuildTask { diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateGuidFromName.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateGuidFromName.cs similarity index 97% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateGuidFromName.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateGuidFromName.cs index 45b991ac5d5..678b32a61a0 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateGuidFromName.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateGuidFromName.cs @@ -6,7 +6,7 @@ using System; using System.Security.Cryptography; -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +namespace Microsoft.DotNet.Build.Tasks.Installers { public class GenerateGuidFromName : BuildTask { diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateJsonObjectString.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateJsonObjectString.cs similarity index 98% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateJsonObjectString.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateJsonObjectString.cs index 2b3f8403630..189b1b3d0eb 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateJsonObjectString.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateJsonObjectString.cs @@ -8,7 +8,7 @@ using System.Linq; using System.Text; -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +namespace Microsoft.DotNet.Build.Tasks.Installers { public class GenerateJsonObjectString : BuildTask { diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMacOSDistributionFile.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateMacOSDistributionFile.cs similarity index 98% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMacOSDistributionFile.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateMacOSDistributionFile.cs index 701e3df339b..434a522218b 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMacOSDistributionFile.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateMacOSDistributionFile.cs @@ -5,7 +5,6 @@ using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using Microsoft.DotNet.Build.Tasks; -using Microsoft.Extensions.DependencyModel; using System; using System.Collections.Generic; using System.IO; diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMsiVersion.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateMsiVersion.cs similarity index 98% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMsiVersion.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateMsiVersion.cs index 54d8ae4435b..fefcb0a13a5 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateMsiVersion.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/GenerateMsiVersion.cs @@ -4,7 +4,7 @@ using Microsoft.Build.Framework; -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +namespace Microsoft.DotNet.Build.Tasks.Installers { // MSI versioning // Encode the CLI version to fit into the MSI versioning scheme - https://msdn.microsoft.com/en-us/library/windows/desktop/aa370859(v=vs.85).aspx diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/StabilizeWixFileId.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/StabilizeWixFileId.cs similarity index 98% rename from src/Microsoft.DotNet.SharedFramework.Sdk/src/StabilizeWixFileId.cs rename to src/Microsoft.DotNet.Build.Tasks.Installers/src/StabilizeWixFileId.cs index 61d516d4b5a..a0a2f1fa1c3 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/StabilizeWixFileId.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/StabilizeWixFileId.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Xml.Linq; -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk +namespace Microsoft.DotNet.Build.Tasks.Installers { /// <summary> /// In a WiX source file, replaces the Id of a File with some given string in order to stabilize diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj index ad7acb25026..a3135bde932 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj @@ -18,7 +18,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(MicrosoftBuildTasksCoreVersion)" /> + <PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCoreVersion)" /> <PackageReference Include="Microsoft.Build" Version="$(MicrosoftBuildVersion)" /> <PackageReference Include="Microsoft.Extensions.DependencyModel" Version="$(MicrosoftExtensionsDependencyModelVersion)" /> <PackageReference Include="NuGet.Packaging" Version="$(NuGetVersion)" /> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs deleted file mode 100644 index 05267536a24..00000000000 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateLightCommandPackageDrop.cs +++ /dev/null @@ -1,246 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Build.Framework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using System.Xml.XPath; - -namespace Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk.src -{ - public class CreateLightCommandPackageDrop : BuildTask - { - private const int _fieldsArtifactId = 0; - private const int _fieldsArtifactPath1 = 6; - private const int _fieldsArtifactPath2 = 1; - - [Required] - public string LightCommandWorkingDir { get; set; } - public bool NoLogo { get; set; } - public bool Fv { get; set; } - public string PdbOut { get; set; } - public string Cultures { get; set; } - public string WixProjectFile { get; set; } - public string ContentsFile { get; set; } - public string OutputsFile { get; set; } - public string BuiltOutputsFile { get; set; } - public ITaskItem [] Loc { get; set; } - public ITaskItem [] Sice { get; set; } - [Required] - public string Out { get; set; } - public ITaskItem [] WixExtensions { get; set; } - [Required] - public ITaskItem [] WixSrcFiles { get; set; } - - [Output] - public string LightCommandPackageNameOutput { get; set; } - // The light command that was originally used to generate the MSI. This is purely used for informational purposes - // and to validate that the light command being created by this task is correct (assist with debugging). - public string OriginalLightCommand { get; set; } - - public override bool Execute() - { - LightCommandPackageNameOutput = Path.GetFileNameWithoutExtension(Out); - string packageDropOutputFolder = Path.Combine(LightCommandWorkingDir, LightCommandPackageNameOutput); - - if (!Directory.Exists(packageDropOutputFolder)) - { - Directory.CreateDirectory(packageDropOutputFolder); - } - XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); - nsmgr.AddNamespace("wix", "http://schemas.microsoft.com/wix/2006/objects"); - - foreach (var wixobj in WixSrcFiles) - { - // copy the file to outputPath - string newWixObjFile = Path.Combine(packageDropOutputFolder, Path.GetFileName(wixobj.ItemSpec)); - Log.LogMessage(LogImportance.Normal, $"Creating modified wixobj file '{newWixObjFile}'..."); - File.Copy(wixobj.ItemSpec, newWixObjFile, true); - - XDocument doc = XDocument.Load(newWixObjFile); - if (doc == null) - { - Log.LogError($"Failed to open the wixobj file '{newWixObjFile}'"); - continue; - } - - // process fragment - WixFile elements - // path in field 7 - string xpath = "//wix:wixObject/wix:section[@type='fragment']/wix:table[@name='WixFile']/wix:row"; - ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath1); - - // process product - WixFile elements - // path in field 7 - xpath = "//wix:wixObject/wix:section[@type='product']/wix:table[@name='WixFile']/wix:row"; - ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath1); - - // process fragment - Binary elements - // path in field 2 - xpath = "//wix:wixObject/wix:section[@type='fragment']/wix:table[@name='Binary']/wix:row"; - ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath2); - - // process product - Icon elements - // path in field 2 - xpath = "//wix:wixObject/wix:section[@type='product']/wix:table[@name='Icon']/wix:row"; - ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath2); - - // process product - WixVariable elements - // path in field 2 - xpath = "//wix:wixObject/wix:section[@type='product']/wix:table[@name='WixVariable']/wix:row"; - ProcessXPath(doc, xpath, packageDropOutputFolder, nsmgr, _fieldsArtifactPath2); - - doc.Save(newWixObjFile); - } - if (Loc != null) - { - foreach (var locItem in Loc) - { - var destinationPath = Path.Combine(packageDropOutputFolder, Path.GetFileName(locItem.ItemSpec)); - File.Copy(locItem.ItemSpec, destinationPath, true); - } - } - - // Write Light command to file - string commandFilename = Path.Combine(packageDropOutputFolder, "light.cmd"); - string commandString = string.Empty; - if(OriginalLightCommand != null) - { - commandString += "REM Original light command" + Environment.NewLine; - commandString += "REM " + OriginalLightCommand + Environment.NewLine; - } - commandString += "REM Modified light command" + Environment.NewLine; - commandString += "light.exe"; - commandString += $" -out {Path.GetFileName(Out)}"; - if (NoLogo) - { - commandString += " -nologo"; - } - if (Cultures != null) - { - commandString += $" -culture:{Cultures}"; - } - if (Loc != null) - { - foreach (var locItem in Loc) - { - commandString += $" -loc:{Path.GetFileName(locItem.ItemSpec)}"; - } - } - if(Fv) - { - commandString += " -fv"; - } - if(PdbOut != null) - { - commandString += $" -pdbout {PdbOut}"; - } - if(WixProjectFile != null) - { - var destinationPath = Path.Combine(packageDropOutputFolder, Path.GetFileName(WixProjectFile)); - File.Copy(WixProjectFile, destinationPath, true); - commandString += $" -wixprojectfile {Path.GetFileName(WixProjectFile)}"; - } - if(ContentsFile != null) - { - commandString += $" -contentsfile {Path.GetFileName(ContentsFile)}"; - } - if (OutputsFile != null) - { - commandString += $" -outputsfile {Path.GetFileName(OutputsFile)}"; - } - if (BuiltOutputsFile != null) - { - commandString += $" -builtoutputsfile {Path.GetFileName(BuiltOutputsFile)}"; - } - if (Sice != null) - { - foreach (var siceItem in Sice) - { - commandString += $" -sice:{siceItem.ItemSpec}"; - } - } - if(WixExtensions != null) - { - foreach(var wixExtension in WixExtensions) - { - commandString += $" -ext {wixExtension.ItemSpec}"; - } - } - if(WixSrcFiles != null) - { - foreach(var wixSrcFile in WixSrcFiles) - { - commandString += $" {Path.GetFileName(wixSrcFile.ItemSpec)}"; - } - } - File.WriteAllText(commandFilename, commandString); - - return !Log.HasLoggedErrors; - } - void ProcessXPath(XDocument doc, string xpath, string outputPath, XmlNamespaceManager nsmgr, int pathField1, int pathField2 = 0) - { - IEnumerable<XElement> iels = doc.XPathSelectElements(xpath, nsmgr); - if (iels != null && iels.Count() > 0) - { - - foreach (XElement row in iels) - { - IEnumerable<XElement> fields = row.XPathSelectElements("wix:field", nsmgr); - if (fields == null || fields.Count() == 0) - { - Log.LogError($"No fields in row ('{xpath}') of document '{doc.BaseUri}'"); - continue; - } - - int count = 0; - string id = ""; - string oldPath = ""; - string newRelativePath = ""; - bool foundArtifact = false; - - foreach (XElement field in fields) - { - if (count == _fieldsArtifactId) - { - id = field.Value; - } - else if (count == pathField1) - { - oldPath = field.Value; - if (!File.Exists(oldPath)) - { - break; - } - - foundArtifact = true; - newRelativePath = Path.Combine(id, Path.GetFileName(oldPath)); - field.Value = newRelativePath; - } - else if (pathField2 != 0 && count == pathField2) - { - field.Value = newRelativePath; - break; - } - count++; - } - - if (foundArtifact) - { - string newFolder = Path.Combine(outputPath, id); - if (!Directory.Exists(newFolder)) - { - Directory.CreateDirectory(newFolder); - } - - File.Copy(oldPath, Path.Combine(outputPath, newRelativePath), true); - } - } - } - } - } -} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index fa1c6af653a..4397f83c0ae 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -58,7 +58,6 @@ <ItemGroup> <_TargetRuntimeIdentifiers Include="$(RuntimeIdentifiers)" /> - <_TargetInstallerRuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> </ItemGroup> <PropertyGroup Condition="'$(RuntimeIdentifiers)' != ''"> @@ -66,153 +65,57 @@ <_RidInRidList Condition="'%(_TargetRuntimeIdentifiers.Identity)' == '$(RuntimeIdentifier)'">true</_RidInRidList> <SkipBuild Condition="'$(_RidInRidList)' != 'true'">true</SkipBuild> </PropertyGroup> - <PropertyGroup Condition="'$(InstallerRuntimeIdentifiers)' != '' and '$(InstallerRuntimeIdentifier)' != ''"> - <!-- Avoid building a project when none of the possible InstallerRuntimeIdentifiers is the current InstallerRuntimeIdentifier. --> - <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> - <SkipBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipBuild> - </PropertyGroup> </Target> - <Target Name="_CalculatePackageInformation"> + <Target Name="_ValidatePackageInformation"> <Error Condition="'$(PlatformPackageType)' != 'TargetingPack' and '$(PlatformPackageType)' != 'RuntimePack' and '$(PlatformPackageType)' != 'AppHostPack' and '$(PlatformPackageType)' != 'ToolPack'" Text="Unknown PlatformPackageType '$(PlatformPackageType)'" /> <Error Condition="'$(_PackageTypeRequiresRid)' == 'true' and '$(RuntimeIdentifier)' == ''" Text="Producing a $(PlatformPackageType) requires a runtime-identifier to be specified." /> - <PropertyGroup> - <PackageId Condition="'$(OverridePackageId)' != ''">$(OverridePackageId)</PackageId> - </PropertyGroup> - <PropertyGroup Condition="'$(PlatformPackageType)' == 'TargetingPack'"> - <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Ref</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Ref</SharedFrameworkArchiveName> - <MacOSComponentNamePackType>pack.targeting</MacOSComponentNamePackType> - </PropertyGroup> - <PropertyGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> - <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Runtime.$(RuntimeIdentifier)</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Runtime</SharedFrameworkArchiveName> - <MacOSComponentNamePackType>sharedframework.$(SharedFrameworkName)</MacOSComponentNamePackType> - </PropertyGroup> - <PropertyGroup Condition="'$(PlatformPackageType)' == 'AppHostPack'"> - <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Host.$(RuntimeIdentifier)</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Host</SharedFrameworkArchiveName> - <MacOSComponentNamePackType>pack.apphost</MacOSComponentNamePackType> - </PropertyGroup> - <PropertyGroup> - <PackageId Condition="'$(OverridePackageId)' == '' and '$(PackageId)' == ''">$(SharedFrameworkName)</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(PackageId)</SharedFrameworkArchiveName> - <MacOSComponentNamePackType Condition="'$(MacOSComponentNamePackType)' == ''">pack.$(PlatformPackageType.ToLower())</MacOSComponentNamePackType> - </PropertyGroup> </Target> <PropertyGroup> <_PackageTypeRequiresRid Condition="'$(PlatformPackageType)' == 'RuntimePack' or '$(PlatformPackageType)' == 'AppHostPack'">true</_PackageTypeRequiresRid> </PropertyGroup> - <PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.sfxproj' or '$(MSBuildProjectExtension)' == '.bundleproj'"> - <!-- Reset BuildDependsOn for project types we know. We update it in the following targets files. --> - <BuildDependsOn></BuildDependsOn> + <PropertyGroup> + <PackageId Condition="'$(OverridePackageId)' != ''">$(OverridePackageId)</PackageId> </PropertyGroup> + <PropertyGroup Condition="'$(PlatformPackageType)' == 'TargetingPack'"> + <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Ref</PackageId> + <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Ref</SharedFrameworkArchiveName> + <MacOSComponentNamePackType>pack.targeting</MacOSComponentNamePackType> + </PropertyGroup> + <PropertyGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> + <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Runtime.$(RuntimeIdentifier)</PackageId> + <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Runtime</SharedFrameworkArchiveName> + <MacOSComponentNamePackType>sharedframework.$(SharedFrameworkName)</MacOSComponentNamePackType> + </PropertyGroup> + <PropertyGroup Condition="'$(PlatformPackageType)' == 'AppHostPack'"> + <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Host.$(RuntimeIdentifier)</PackageId> + <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Host</SharedFrameworkArchiveName> + <MacOSComponentNamePackType>pack.apphost</MacOSComponentNamePackType> + </PropertyGroup> <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);_GetSkipBuildProps</BuildDependsOn> - <_GlobalPropertiesToRemoveForPublish> - GenerateCrossArchMsi; - GenerateMSI; - GeneratePkg; - GenerateDeb; - GenerateRpm; - IsShipping; - ComponentMsiFile; - InstallerRuntimeIdentifier; - InstallerTargetArchitecture; - CrossArchContentsArch - </_GlobalPropertiesToRemoveForPublish> + <PackageId Condition="'$(OverridePackageId)' == '' and '$(PackageId)' == ''">$(SharedFrameworkName)</PackageId> + <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(PackageId)</SharedFrameworkArchiveName> + <MacOSComponentNamePackType Condition="'$(MacOSComponentNamePackType)' == ''">pack.$(PlatformPackageType.ToLower())</MacOSComponentNamePackType> </PropertyGroup> - - <ItemGroup> - <_GlobalPropertiesToRemoveForPublish Include="$(_GlobalPropertiesToRemoveForPublish)" /> - </ItemGroup> - + + <PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.sfxproj'"> + <!-- Reset BuildDependsOn for project types we know. We update it in the following targets files. --> + <BuildDependsOn></BuildDependsOn> + </PropertyGroup> + <Import Project="$(MSBuildThisFileDirectory)sharedfx.targets" Condition="'$(MSBuildProjectExtension)' == '.sfxproj'" /> <Import Project="$(MSBuildThisFileDirectory)archive.targets" Condition="'$(GenerateArchive)' == 'true'" /> - <Target Name="_GetTargetOSArchInfo"> - <Error Condition="'$(InstallerRuntimeIdentifier)' == ''" - Text="An InstallerRuntimeIdentifier must be specified when building installers." /> - <PropertyGroup> - <TargetRuntimeOS>$(InstallerRuntimeIdentifier.Substring(0, $(InstallerRuntimeIdentifier.LastIndexOf('-'))))</TargetRuntimeOS> - <TargetArchitecture Condition="'$(TargetArchitecture)' == ''">$(InstallerRuntimeIdentifier.Substring($(InstallerRuntimeIdentifier.LastIndexOf('-'))).TrimStart('-'))</TargetArchitecture> - <InstallerTargetArchitecture Condition="'$(InstallerTargetArchitecture)' == ''">$(TargetArchitecture)</InstallerTargetArchitecture> - </PropertyGroup> - <ItemGroup> - <CrossArchMsiToBuild Include="@(CrossArchSdkMsiInstallerArch)" Exclude="$(TargetArchitecture)" /> - </ItemGroup> - <PropertyGroup> - <_osSupportsWixBasedInstallers Condition="$([MSBuild]::IsOsPlatform(Windows)) and '$(TargetRuntimeOS)' == 'win'">true</_osSupportsWixBasedInstallers> - - <_osArchSupportsWixBasedInstallers>$(_osSupportsWixBasedInstallers)</_osArchSupportsWixBasedInstallers> - <_osArchSupportsWixBasedInstallers Condition="'$(TargetArchitecture)' == 'arm'">false</_osArchSupportsWixBasedInstallers> - </PropertyGroup> - </Target> - - <Target Name="_GetVersionInfo"> - <PropertyGroup> - <IncludePreReleaseLabelInPackageVersion Condition="'$(DotNetFinalVersionKind)' != 'release'">true</IncludePreReleaseLabelInPackageVersion> - <IncludePreReleaseLabelInPackageVersion Condition="'$(SuppressFinalPackageVersion)' == 'true'">true</IncludePreReleaseLabelInPackageVersion> - <IncludePreReleaseLabelInPackageVersion Condition="'$(IsShipping)' != 'true'">true</IncludePreReleaseLabelInPackageVersion> - </PropertyGroup> - </Target> - - <Target Name="_GetProductBrandName" DependsOnTargets="_GetVersionInfo"> - <PropertyGroup - Condition=" - '$(ReleaseBrandSuffix)' == '' and - '$(PreReleaseVersionLabel)' != '' and - '$(PreReleaseVersionIteration)' != ''"> - <!-- Convert 'preview.7' to 'Preview 7'. - 'preview' will come from the pre-release version iteration and the numeric value - will be the PreReleaseVersionIteration. --> - - <ReleaseBrandSuffix>$(PreReleaseVersionLabel.Substring(0,1).ToUpperInvariant())</ReleaseBrandSuffix> - <ReleaseBrandSuffix>$(ReleaseBrandSuffix)$(PreReleaseVersionLabel.Substring(1))</ReleaseBrandSuffix> - <ReleaseBrandSuffix>$(ReleaseBrandSuffix) $(PreReleaseVersionIteration)</ReleaseBrandSuffix> - </PropertyGroup> - - <Error - Text="When building installers a ProductBrandPrefix is required." - Condition="'$(ProductBrandPrefix)' == ''" /> - <Error - Text="When building installers for a tool pack a PackageBrandNameSuffix is required." - Condition="'$(PackageBrandNameSuffix)' == '' and '$(PlatformPackageType)' == 'ToolPack' and '$(MSBuildProjectExtension)' != '.bundleproj'" /> - <Error - Text="When building a bundle installer, a BundleNameSuffix must be specified." - Condition="'$(BundleNameSuffix)' == '' and '$(MSBuildProjectExtension)' == '.bundleproj'" /> - - <PropertyGroup> - <ProductBrandSuffix>$(VersionPrefix)</ProductBrandSuffix> - <ProductBrandSuffix Condition="'$(ReleaseBrandSuffix)'!=''">$(VersionPrefix) $(ReleaseBrandSuffix)</ProductBrandSuffix> - - <ProductBrandName Condition="'$(PlatformPackageType)' == 'TargetingPack'">$(ProductBrandPrefix) Targeting Pack - $(ProductBrandSuffix)</ProductBrandName> - <ProductBrandName Condition="'$(PlatformPackageType)' == 'RuntimePack'">$(ProductBrandPrefix) Runtime - $(ProductBrandSuffix)</ProductBrandName> - <ProductBrandName Condition="'$(PlatformPackageType)' == 'AppHostPack'">$(ProductBrandPrefix) AppHost Pack - $(ProductBrandSuffix)</ProductBrandName> - <ProductBrandName Condition="'$(MSBuildProjectExtension)' == '.bundleproj'">$(ProductBrandPrefix) $(BundleNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> - <ProductBrandName Condition="'$(ProductBrandName)' == ''">$(ProductBrandPrefix) $(PackageBrandNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> - </PropertyGroup> - </Target> - - <PropertyGroup> - <InstallerRuntimeIdentifier Condition="'$(InstallerRuntimeIdentifier)' == ''">$(RuntimeIdentifier)</InstallerRuntimeIdentifier> - </PropertyGroup> - - <Import Project="$(MSBuildThisFileDirectory)installer.targets" - Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' != ''" /> - <Import Project="$(MSBuildThisFileDirectory)installer.multirid.targets" - Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' == ''" /> - <Import Project="$(MSBuildThisFileDirectory)bundle.targets" - Condition="'$(MSBuildProjectExtension)' == '.bundleproj'" /> + <Import Project="windows/wix.targets" /> </Project> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props index f424c378650..e0a1690cbf7 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props @@ -1,6 +1,6 @@ <Project> <PropertyGroup> <!-- Don't generate archives for bundles by default. --> - <GenerateArchive Condition="'$(MSBuildProjectExtension)' != '.bundleproj'">true</GenerateArchive> + <GenerateArchive>true</GenerateArchive> </PropertyGroup> </Project> \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets index ebb96887663..06ace865052 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets @@ -1,6 +1,6 @@ <Project> <Target Name="_CreateSharedFrameworkArchive" - DependsOnTargets="_CalculatePackageInformation" + DependsOnTargets="_ValidatePackageInformation" Condition="'$(SkipBuild)' != 'true'"> <PropertyGroup> <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/</_SharedFrameworkOutputPathRoot> @@ -8,9 +8,8 @@ <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> </PropertyGroup> <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkToDisk" - Properties="SharedFrameworkOutputPath=$(_SharedFrameworkOutputPathRoot)" - RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> + Targets="PublishToDisk" + Properties="OutputPath=$(_SharedFrameworkOutputPathRoot)" /> <MakeDir Directories="$(PackageOutputPath)" /> <ZipDirectory SourceDirectory="$(_SharedFrameworkOutputPathRoot)" @@ -24,7 +23,7 @@ </Target> <Target Name="_CreateSharedFrameworkSymbolsArchive" - DependsOnTargets="_CalculatePackageInformation" + DependsOnTargets="_ValidatePackageInformation" Condition="'$(CreateSharedFrameworkSymbolsArchive)' == 'true' and '$(SkipBuild)' != 'true'"> <PropertyGroup> <_SharedFrameworkSymbolsOutputPathRoot>$(IntermediateOutputPath)sharedFrameworkSymbols/</_SharedFrameworkSymbolsOutputPathRoot> @@ -32,8 +31,8 @@ <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> </PropertyGroup> <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkSymbolsToDisk" - Properties="SharedFrameworkSymbolsOutputPath=$(_SharedFrameworkSymbolsOutputPathRoot)" /> + Targets="PublishSymbolsToDisk" + Properties="SymbolsOutputPath=$(_SharedFrameworkSymbolsOutputPathRoot)" /> <MakeDir Directories="$(PackageOutputPath)" /> <ZipDirectory SourceDirectory="$(_SharedFrameworkSymbolsOutputPathRoot)" diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 8a1096b8e5f..2db62cab1f4 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -27,7 +27,7 @@ </Target> <Target Name="_PrepareSharedFrameworkForReadyToRun" - DependsOnTargets="_CalculatePackageInformation; + DependsOnTargets="_ValidatePackageInformation; GetSharedFrameworkFilesForReadyToRun" Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <ItemGroup> @@ -57,7 +57,7 @@ </Target> <Target Name="GetFilesToPackage" - DependsOnTargets="_CalculatePackageInformation; + DependsOnTargets="_ValidatePackageInformation; ResolveFrameworkReferences; ResolveLockFileCopyLocalFiles; ResolveReferences; @@ -269,7 +269,7 @@ --> <UsingTask TaskName="GeneratePlatformManifestEntriesFromFileList" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> <Target Name="_GeneratePlatformManifestFromRuntimePack" - DependsOnTargets="_CalculatePackageInformation" + DependsOnTargets="_ValidatePackageInformation" Condition="'$(PlatformPackageType)' == 'TargetingPack' and '$(UseTemplatedPlatformManifest)' != 'true'"> <PropertyGroup> @@ -445,32 +445,32 @@ </ItemGroup> </Target> - <Target Name="PublishSharedFrameworkToDisk" + <Target Name="PublishToDisk" DependsOnTargets="GetFilesToPublish"> - <Error Condition="'$(SharedFrameworkOutputPath)' == ''" Text="Publishing a shared framework to disk requires the SharedFrameworkOutputPath to be set to the root of the path to write to." /> + <Error Condition="'$(OutputPath)' == ''" Text="Publishing a shared framework to disk requires the OutputPath to be set to the root of the path to write to." /> <Copy SourceFiles="@(FilesToPublish)" - DestinationFolder="$(SharedFrameworkOutputPath)%(FilesToPublish.TargetPath)%(FilesToPublish.Culture)" + DestinationFolder="$(OutputPath)%(FilesToPublish.TargetPath)%(FilesToPublish.Culture)" Condition="'%(FilesToPublish.IsSymbolFile)' != 'true'" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="true" /> <!-- Fix file permissions in the layout dir. --> <!-- Reset everything to user readable/writeable and group and world readable. --> - <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(SharedFrameworkOutputPath)" -type f -name "*" -exec chmod 644 {} \;' /> + <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(OutputPath)" -type f -name "*" -exec chmod 644 {} \;' /> <!-- Generally, dylibs and sos have 'x'. --> - <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(SharedFrameworkOutputPath)" -type f -name "*.dylib" -exec chmod 755 {} \;' /> - <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(SharedFrameworkOutputPath)" -type f -name "*.so" -exec chmod 755 {} \;' /> + <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(OutputPath)" -type f -name "*.dylib" -exec chmod 755 {} \;' /> + <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(OutputPath)" -type f -name "*.so" -exec chmod 755 {} \;' /> <!-- Executables (those without dots) are executable. --> - <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(SharedFrameworkOutputPath)" -type f ! -name "*.*" -exec chmod 755 {} \;' /> + <Exec Condition="!$([MSBuild]::IsOsPlatform(Windows))" Command='find "$(OutputPath)" -type f ! -name "*.*" -exec chmod 755 {} \;' /> </Target> - <Target Name="PublishSharedFrameworkSymbolsToDisk" + <Target Name="PublishSymbolsToDisk" DependsOnTargets="GetFilesToPublish"> - <Error Condition="'$(SharedFrameworkSymbolsOutputPath)' == ''" Text="Publishing a shared framework to disk requires the SharedFrameworkOutputPath to be set to the root of the path to write to." /> + <Error Condition="'$(SymbolsOutputPath)' == ''" Text="Publishing a shared framework to disk requires the OutputPath to be set to the root of the path to write to." /> <Copy SourceFiles="@(FilesToPublish)" - DestinationFolder="$(SharedFrameworkSymbolsOutputPath)%(FilesToPublish.Culture)" + DestinationFolder="$(SymbolsOutputPath)%(FilesToPublish.Culture)" Condition="'%(FilesToPublish.IsSymbolFile)' == 'true'" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="true" /> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets index 6845efdf32c..3d899ba7b89 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets @@ -1,549 +1,33 @@ <Project> - <!-- - These targets use MSBuild Exec tasks to run WiX 3 toolset commands. - - WiX 4 is expected to support running in .NET Core. Once using WiX 4, we can (more easily) remove - this file and switch to wixproj. See https://github.com/wixtoolset/issues/issues/5627 - --> - - <UsingTask TaskName="CreateLightCommandPackageDrop" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> - <UsingTask TaskName="ExecWithRetries" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> - <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> - <UsingTask TaskName="GenerateCurrentVersion" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> - <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> - <UsingTask TaskName="GenerateGuidFromName" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> - - <!-- - Acquire WiX tools, if not present. - --> - <Target Name="AcquireWix" - DependsOnTargets="GetAcquireWixProperties"> - <MSBuild - Projects="$(AcquireWixProjectFile)" - Targets="AcquireWixCore" - Properties="BaseIntermediateOutputPath=$(BaseIntermediateOutputPath); - RepoRoot=$(RepoRoot)" /> - </Target> - - <Target Name="GetAcquireWixProperties"> - - <PropertyGroup> - <_WixIntermediateOutputPath>$(BaseIntermediateOutputPath)wix</_WixIntermediateOutputPath> - </PropertyGroup> - - <PropertyGroup> - <WixVersion>3.14.0.4118</WixVersion> - <WixToolsDir>$(BaseIntermediateOutputPath)WixTools.$(WixVersion)/</WixToolsDir> - <!-- Used in WiX targets to locate files. --> - <WixInstallPath>$(WixToolsDir)</WixInstallPath> - <WixTargetsPath>$(WixToolsDir)wix.targets</WixTargetsPath> - <WixObjDir>$(IntermediateOutputPath)/wix/</WixObjDir> - <WixObjDir Condition="'$(RuntimeIdentifier)' == ''">$(IntermediateOutputPath)/$(InstallerRuntimeIdentifier)/wix/</WixObjDir> - <LightCommandObjDir>$(IntermediateOutputPath)/lightcommand/</LightCommandObjDir> - <MsiArch>$(InstallerTargetArchitecture)</MsiArch> - - <AcquireWixProjectFile>$(MSBuildThisFileDirectory)..\acquisition\acquire-wix\acquire-wix.proj</AcquireWixProjectFile> - <WixDownloadFilename>wix.$(WixVersion).zip</WixDownloadFilename> - <WixDownloadUrl>https://dotnetcli.azureedge.net/build/wix/$(WixDownloadFilename)</WixDownloadUrl> - <WixDestinationPath>$(WixToolsDir)$(WixDownloadFilename)</WixDestinationPath> - <WixDownloadSentinel>$(WixToolsDir)WixDownload.$(WixVersion).sentinel</WixDownloadSentinel> - </PropertyGroup> - </Target> - - <Target Name="_GenerateMsiVersionString"> - <PropertyGroup> - <VersionPadding Condition="'$(VersionPadding)'==''">5</VersionPadding> - <!-- Using the following default comparison date will produce versions that align with our internal build system. --> - <VersionComparisonDate Condition="'$(VersionComparisonDate)'==''">1996-04-01</VersionComparisonDate> - </PropertyGroup> - - <GenerateCurrentVersion - SeedDate="$([System.DateTime]::Now.ToString(yyyy-MM-dd))" - OfficialBuildId="$(OfficialBuildId)" - ComparisonDate="$(VersionComparisonDate)" - Padding="$(VersionPadding)"> - <Output PropertyName="BuildNumberMajor" TaskParameter="GeneratedVersion" /> - <Output PropertyName="BuildNumberMinor" TaskParameter="GeneratedRevision" /> - </GenerateCurrentVersion> - - <GenerateMsiVersion - Major="$(MajorVersion)" - Minor="$(MinorVersion)" - Patch="$(PatchVersion)" - BuildNumberMajor="$(BuildNumberMajor)" - BuildNumberMinor="$(BuildNumberMajor)"> - <Output TaskParameter="MsiVersion" PropertyName="MsiVersionString" /> - </GenerateMsiVersion> - </Target> - - <!-- - Generate bundle upgrade code. This code needs to be constant within a product band for upgrades. - --> - <Target Name="GetBundleUpgradeCode" - DependsOnTargets="GetWixBuildConfiguration" - Condition=" - '$(GenerateExeBundle)' == 'true' and - '$(UpgradeCode)' == ''"> - <Error - Condition="'$(BundleInstallerUpgradeCodeSeed)' == ''" - Text="BundleInstallerUpgradeCodeSeed not defined. Required to produce a stable bundle upgrade code." /> - - <PropertyGroup> - <BundleInstallerOutputGuidString>$(BundleInstallerUpgradeCodeSeed) $(MajorVersion).$(MinorVersion) $(RuntimeIdentifier)</BundleInstallerOutputGuidString> - </PropertyGroup> - - <GenerateGuidFromName Name="$(BundleInstallerOutputGuidString)"> - <Output TaskParameter="GeneratedGuid" PropertyName="UpgradeCode" /> - </GenerateGuidFromName> - </Target> - - <!-- - If UpgradeCode isn't already set, generate one based on installer full path. - --> - <Target Name="_GetUpgradeCode" - DependsOnTargets="GetWixBuildConfiguration" - Condition="'$(UpgradeCode)' == ''"> - <GenerateGuidFromName Name="$(_OutInstallerFile)"> - <Output TaskParameter="GeneratedGuid" PropertyName="UpgradeCode" /> - </GenerateGuidFromName> - </Target> - - <Target Name="_UseProductWixProject"> - <ItemGroup> - <WixExtensions Include="WixUIExtension.dll" /> - <WixExtensions Include="WixDependencyExtension.dll" /> - <WixExtensions Include="WixUtilExtension.dll" /> - - <WixSrcFile Include="$(MSBuildThisFileDirectory)product/product.wxs" /> - <WixSrcFile Include="$(MSBuildThisFileDirectory)product/provider.wxs" /> - </ItemGroup> - </Target> - - <Target Name="UseBundleWixProject"> - <ItemGroup> - <WixExtensions Include="WixBalExtension.dll" /> - <WixExtensions Include="WixTagExtension.dll" /> - <WixExtensions Include="WixUtilExtension.dll" /> - - <WixSrcFile Include="$(MSBuildThisFileDirectory)bundle/bundle.wxs" /> - </ItemGroup> - </Target> - <Target Name="_GetFrameworkPackWixConfiguration" - DependsOnTargets="_UseProductWixProject" - Condition="'$(GenerateExeBundle)' != 'true'"> + BeforeTargets="GetInstallerWixConfiguration" + DependsOnTargets="PublishFilesForWixInstaller"> <PropertyGroup> - <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/</_SharedFrameworkOutputPathRoot> - <OutputFilesCandleVariable Condition="'$(OutputFilesCandleVariable)' == ''">PackSrc</OutputFilesCandleVariable> + <UseCustomDirectoryHarvesting>true</UseCustomDirectoryHarvesting> + </PropertyGroup> + <PropertyGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> + <WixIncludeRegistryKeys>true</WixIncludeRegistryKeys> </PropertyGroup> - - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSharedFrameworkToDisk" - Properties="SharedFrameworkOutputPath=$(_SharedFrameworkOutputPathRoot)" - RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> - - <ItemGroup Condition="'$(PlatformPackageType)' != 'RuntimePack'"> - <DirectoryToHarvest - Include="$(_SharedFrameworkOutputPathRoot)" - Condition="'$(UseCustomDirectoryHarvesting)' != 'true'" - Name="install-files" - SubstituteVar="$(OutputFilesCandleVariable)" - ComponentGroupName="InstallFiles" - DirectoryRef="DOTNETHOME" /> - <CandleVariables Include="$(OutputFilesCandleVariable)" Value="$(_SharedFrameworkOutputPathRoot)" - Condition="'$(UseCustomDirectoryHarvesting)' == 'true'" /> - </ItemGroup> <ItemGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <DirectoryToHarvest - Include="$(_SharedFrameworkOutputPathRoot)shared/" + Include="$(FilesOutputPathRoot)shared/" Name="install-shared-framework" SubstituteVar="SharedFrameworkSrc" ComponentGroupName="InstallFiles" DirectoryRef="SHARED" /> <WixSrcFile Include="$(MSBuildThisFileDirectory)product/sharedfxdir.wxs" /> - <WixSrcFile Include="$(MSBuildThisFileDirectory)product/registrykeys.wxs" /> <CandleVariables Include="AuthoredRegistryKeys" Value="true" /> <CandleVariables Include="RegKeyNugetVersionExistence" Value="true" /> </ItemGroup> - <ItemGroup Condition="'$(PlatformPackageType)' == 'RuntimePack' and '$(IncludeWerRelatedKeys)' == 'true'"> - <WixSrcFile Include="$(MSBuildThisFileDirectory)product/werrelatedkeys.wxs" /> - <CandleVariables Include="WerRelatedKeys" Value="true" /> - </ItemGroup> - - <ItemGroup Condition="'$(PlatformPackageType)' == 'RuntimePack' and '$(IncludeBreadcrumbStoreFolder)' == 'true'"> - <WixSrcFile Include="$(MSBuildThisFileDirectory)product/breadcrumbstorefolder.wxs" /> - <CandleVariables Include="BreadcrumbStoreFolder" Value="true" /> - </ItemGroup> - - <ItemGroup Condition="'$(WixIncludeRegistryKeys)' == 'true'"> - <WixSrcFile Include="$(MSBuildThisFileDirectory)product/registrykeys.wxs" /> - </ItemGroup> - </Target> - - <Target Name="GetBundleWixConfiguration" - Condition="'$(GenerateExeBundle)' == 'true'" - DependsOnTargets=" - UseBundleWixProject; - GetBundledMsiFiles"> - <Error Text="A bundle theme directory property must be specified with the BundleThemeDirectory property." - Condition="'$(BundleThemeDirectory)' == ''" /> - - <ItemGroup> - <LocFile Include="$(BundleThemeDirectory)\theme\**\bundle.wxl" /> - <LocDirName Include="$([System.String]::new('%(LocFile.RecursiveDir)').TrimEnd('\'))" /> - - <CandleVariables Include="DisplayVersion" Value="$(MajorVersion).$(MinorVersion).$(PatchVersion).$(BuildNumberMajor)" /> - <CandleVariables Include="ProductBandVersion" Value="$(MajorVersion).$(MinorVersion)" /> - <CandleVariables Include="FrameworkDisplayVersion" Value="$(ProductVersion)" /> - <CandleVariables Include="LcidList" Value="@(LocDirName)" /> - <CandleVariables Include="BundleThmDir" Value="$(BundleThemeDirectory)" /> - - <CandleVariables Include="DotNetBackgroundPngFile" Value="$(MSBuildThisFileDirectory)..\resources\dotnetbackground.png" /> - <CandleVariables Include="DotNetDummyEulaFile" Value="$(MSBuildThisFileDirectory)bundle\dummyEula.rtf" /> - </ItemGroup> - - <PropertyGroup> - <_OutInstallerFile>$(_InstallerFile)</_OutInstallerFile> - </PropertyGroup> - </Target> - - <!-- Set up information to pass to WiX, depending on the type of installer being created. --> - <Target Name="GetWixBuildConfiguration" - DependsOnTargets=" - AcquireWix; - _GetInstallerProperties; - _GenerateMsiVersionString; - _GetFrameworkPackWixConfiguration; - GetBundleWixConfiguration"> <PropertyGroup> - <_OutInstallerFile Condition="'$(_OutInstallerFile)' == ''">$(_InstallerFile)</_OutInstallerFile> - </PropertyGroup> - <PropertyGroup> - <!-- - Native arm64 MSI packages require version 500 of MSI database schema, see: - https://docs.microsoft.com/en-us/windows/win32/msi/using-64-bit-windows-installer-packages - --> - <WixInstallerVersion Condition="'$(WixInstallerVersion)' == '' and '$(MsiArch)' == 'arm64'">500</WixInstallerVersion> - <WixInstallerVersion Condition="'$(WixInstallerVersion)' == ''">200</WixInstallerVersion> - </PropertyGroup> - - <ItemGroup> - <CandleVariables Include="MicrosoftEula" Value="$(MSBuildThisFileDirectory)eula.rtf" /> - <CandleVariables Include="InstallerVersion" Value="$(WixInstallerVersion)" /> - </ItemGroup> - </Target> - - <!-- - Ensure MSIs are built and signed (if necessary), then obtain all paths to MSIs to bundle from - the bundle references. - --> - <Target Name="GetBundledMsiFiles" DependsOnTargets="_GetBundledComponentInstallers"> - <ItemGroup> - <CandleVariables Include="ChainedDotNetPackageFiles" Value="@(_BundledComponents)" /> - </ItemGroup> - </Target> - - <Target Name="RunHeatHarvester" - Condition="'@(DirectoryToHarvest)' != ''" - DependsOnTargets="GetWixBuildConfiguration"> - <ItemGroup> - <DirectoryToHarvest - WixSourceFile="$(WixObjDir)%(Name).wxs" - WixObjFile="$(WixObjDir)%(Name).wixobj" /> - - <DirectoryToHarvest - Command="heat.exe ^ - dir "%(Identity)" ^ - -nologo ^ - -template fragment ^ - -sreg ^ - -ag ^ - -var var.%(SubstituteVar) ^ - -cg %(ComponentGroupName) ^ - -srd ^ - -dr %(DirectoryRef) ^ - -out %(WixSourceFile)" /> - - <CandleVariables Include="InstallFiles" Value="true" /> - </ItemGroup> - - <Exec - Command="%(DirectoryToHarvest.Command)" - WorkingDirectory="$(WixToolsDir)" - StandardOutputImportance="normal" /> - - <!-- - Currently FileElementToStabilize assumes a single DirectoryToHarvest. If there were multiple, - the task would expect exactly one match in each file, which isn't likely to be the case. But, - there is no known scenario to have multiple DirectoryToHarvest and use FileElementToStabilize. - --> - <StabilizeWixFileId - Condition="'@(HeatOutputFileElementToStabilize)' != ''" - SourceFile="%(DirectoryToHarvest.WixSourceFile)" - OutputFile="%(DirectoryToHarvest.WixSourceFile)" - FileElementToStabilize="@(HeatOutputFileElementToStabilize)" /> - </Target> - - <Target Name="RunCandleCompiler" - DependsOnTargets=" - GetWixBuildConfiguration; - GetBundleUpgradeCode; - _GetUpgradeCode; - _GenerateMsiVersionString"> - <PropertyGroup> - <WixDependencyKeyName Condition="'$(WixDependencyKeyName)' == ''">$(InstallerName.Replace('-', '_'))</WixDependencyKeyName> <RegKeyProductName Condition="'$(RegKeyProductName)' == '' and '$(SharedFrameworkName)' != ''">sharedfx\$(SharedFrameworkName)</RegKeyProductName> </PropertyGroup> - <ItemGroup> - <CandleVariables Include="SharedWixDir" Value="$(MSBuildThisFileDirectory.TrimEnd('\'))" /> - <CandleVariables Include="DependencyKeyName" Value="$(WixDependencyKeyName)" /> - - <CandleVariables Include="%(DirectoryToHarvest.SubstituteVar)" Value="%(DirectoryToHarvest.Identity)" /> - - <CandleVariables Include="ExtraComponentGroupRefIds" Value="@(WixExtraComponentGroupRefId)" Condition="'@(WixExtraComponentGroupRefId)' != ''" /> <CandleVariables Include="FrameworkName" Value="$(SharedFrameworkName)" Condition="'$(SharedFrameworkName)' != ''" /> - <CandleVariables Include="RegKeyProductName" Value="$(RegKeyProductName)" Condition="'$(RegKeyProductName)' != ''" /> - - <CandleVariables Include="ProductMoniker" Value="$(ProductBrandName)" /> - <CandleVariables Include="BuildVersion" Value="$(MsiVersionString)" /> - <CandleVariables Include="NugetVersion" Value="$(Version)" /> - <CandleVariables Include="TargetArchitectureDescription" Value="$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart)" /> - <CandleVariables Include="UpgradeCode" Value="$(UpgradeCode)" /> - - <!-- If this is a cross-arch MSI, add target arch to the dependency key for uniqueness. --> - <CandleVariables Include="CrossArchContentsPlatformPart" Value="$(CrossArchContentsBuildPart.Replace('-', '_'))" /> </ItemGroup> - - <PropertyGroup> - <_wixArgs></_wixArgs> - <_wixArgs>$(_wixArgs) -nologo</_wixArgs> - <_wixArgs>$(_wixArgs) -arch $(MsiArch)</_wixArgs> - <_wixArgs>$(_wixArgs) -out "$(WixObjDir)"</_wixArgs> - - <_wixArgs>$(_wixArgs) @(WixExtensions -> '-ext %(Identity)', ' ')</_wixArgs> - <_wixArgs>$(_wixArgs) @(CandleVariables -> '-d%(Identity)="%(Value)"', ' ')</_wixArgs> - <_wixArgs>$(_wixArgs) @(WixSrcFile -> '"%(FullPath)"', ' ')</_wixArgs> - <_wixArgs>$(_wixArgs) @(DirectoryToHarvest -> '"%(WixSourceFile)"', ' ')</_wixArgs> - </PropertyGroup> - - <Exec - Command="candle.exe $(_wixArgs)" - WorkingDirectory="$(WixToolsDir)" - StandardOutputImportance="normal" /> </Target> - - <Target Name="RunLightLinker" - DependsOnTargets=" - GetWixBuildConfiguration; - RunHeatHarvester; - RunCandleCompiler"> - <PropertyGroup> - <_wixArgs></_wixArgs> - <_wixArgs>$(_wixArgs) -nologo</_wixArgs> - <_wixArgs>$(_wixArgs) -cultures:en-us</_wixArgs> - <_wixArgs>$(_wixArgs) -out $(_OutInstallerFile)</_wixArgs> - - <_wixArgs>$(_wixArgs) @(WixExtensions -> '-ext %(Identity)', ' ')</_wixArgs> - <_wixArgs>$(_wixArgs) @(WixSrcFile -> '"$(WixObjDir)%(Filename).wixobj"', ' ')</_wixArgs> - <_wixArgs>$(_wixArgs) @(DirectoryToHarvest -> '"%(WixObjFile)"', ' ')</_wixArgs> - <_lightCommand>light.exe $(_wixArgs)</_lightCommand> - - <_LightCommandPackagesDir>$(ArtifactsNonShippingPackagesDir)</_LightCommandPackagesDir> - </PropertyGroup> - - <!-- - Run light.exe with retries. This hardens against interference by Windows Defender by giving - Defender time to catch up. Light creates a file then immediately moves it, which fails when - Defender is holding it open. Uses a small base time because it resolves itself quickly and we - don't want to delay the build very long if it's an actual build authoring error. - --> - <ExecWithRetries - Command="$(_lightCommand)" - WorkingDirectory="$(WixToolsDir)" - StandardOutputImportance="normal" - IgnoreStandardErrorWarningFormat="true" - RetryDelayBase="2" /> - - <CreateLightCommandPackageDrop - OriginalLightCommand="$(_lightCommand)" - LightCommandWorkingDir="$(LightCommandObjDir)" - NoLogo="true" - Cultures="en-us" - Out="$(_OutInstallerFile)" - WixExtensions="@(WixExtensions)" - WixSrcFiles="@(WixSrcFile -> '$(WixObjDir)%(Filename).wixobj');@(DirectoryToHarvest -> '%(WixObjFile)')"> - <Output TaskParameter="LightCommandPackageNameOutput" PropertyName="_LightCommandPackageNameOutput" /> - </CreateLightCommandPackageDrop> - - <MakeDir Directories="$(_LightCommandPackagesDir)" /> - - <ZipDirectory - DestinationFile="$(_LightCommandPackagesDir)/LightCommandPackage-$(_LightCommandPackageNameOutput).zip" - Overwrite="true" - SourceDirectory="$(LightCommandObjDir)/$(_LightCommandPackageNameOutput)" /> - </Target> - - <!-- - Entry point for an MSBuild call: creates NuGet packages suitable for VS insertion. - --> - <Target Name="GenerateVSInsertionNupkg" - DependsOnTargets=" - GetInstallerGenerationFlags; - GenerateCurrentArchVSInsertionNupkg; - GenerateCrossArchVSInsertionNupkg" /> - - <Target Name="GenerateCurrentArchVSInsertionNupkg" - Condition="'$(GenerateMSI)' == 'true'"> - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="CreateWixInstaller" - Properties="GenerateMSI=true" - RemoveProperties="GenerateCrossArchMsi"> - <Output TaskParameter="TargetOutputs" PropertyName="_ComponentMsiFile" /> - - </MSBuild> - - <!-- - Run the nupkg creation code with IsShipping=false to use prerelease versions: this package - must not be stable to avoid mutation conflicts, even though the project itself may be shipping - and therefore stabilized. - - Also pass in the path to the MSI file to pack up because its file name is based on - stabilization status. - --> - <MSBuild - Projects="$(MSBuildProjectFullPath)" - Targets="GenerateVSInsertionNupkgCore" - Properties=" - IsShipping=false; - ComponentMsiFile=$(_ComponentMsiFile)" /> - </Target> - - <Target Name="GenerateCrossArchVSInsertionNupkg" - Condition="'$(GenerateCrossArchMsi)' == 'true'" - DependsOnTargets=" - _GetInstallerProperties; - GenerateCrossArchVSInsertionNupkgPerArch" /> - - <Target Name="GenerateCrossArchVSInsertionNupkgPerArch" - Condition="'@(CrossArchMsiToBuild)' != ''" - Inputs="%(CrossArchMsiToBuild.Identity)" - Outputs="batching-on-CrossArchMsiToBuild"> - <!-- - Get the cross-arch MSI to pack into an insertion package. Do this separately from the - GenerateVSInsertionNupkgCore call because IsShipping influences the file name. - --> - <MSBuild - Projects="$(MSBuildProjectFullPath)" - Targets="CreateCrossArchWixInstaller" - Properties=" - GenerateCrossArchMsi=true; - InstallerTargetArchitecture=%(CrossArchMsiToBuild.Identity); - CrossArchContentsArch=$(TargetArchitecture)" - RemoveProperties="GenerateMSI"> - <Output TaskParameter="TargetOutputs" PropertyName="CrossArchMsiFile" /> - </MSBuild> - - <MSBuild - Projects="$(MSBuildProjectFullPath)" - Targets="GenerateVSInsertionNupkgCore" - Properties=" - InstallerTargetArchitecture=%(CrossArchMsiToBuild.Identity); - CrossArchContentsArch=$(TargetArchitecture); - IsShipping=false; - ComponentMsiFile=$(CrossArchMsiFile)" /> - </Target> - - <!-- - Acquire NuGet.exe, if not present. - --> - <Target Name="_AcquireNuGetExe" - DependsOnTargets="_GetAcquireNuGetExeProperties"> - <MSBuild - Projects="$(AcquireNuGetExeProjectFile)" - Targets="AcquireNuGetExeCore" - Properties="BaseIntermediateOutputPath=$(BaseIntermediateOutputPath); - RepoRoot=$(RepoRoot)" /> - </Target> - - <Target Name="_GetAcquireNuGetExeProperties"> - <PropertyGroup> - <AcquireNuGetExeProjectFile>$(MSBuildThisFileDirectory)..\acquisition\acquire-nuget-exe\acquire-nuget-exe.proj</AcquireNuGetExeProjectFile> - <!-- Using 3.5.0 to workaround https://github.com/NuGet/Home/issues/5016 --> - <NuGetExeDownloadUrl>https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe</NuGetExeDownloadUrl> - <NuGetExeToolDir>$(BaseIntermediateOutputPath)nuget\</NuGetExeToolDir> - <NuGetExeFile>$(NuGetExeToolDir)NuGet.exe</NuGetExeFile> - </PropertyGroup> - </Target> - - <Target Name="GenerateVSInsertionNupkgCore" - DependsOnTargets=" - _GetTargetOSArchInfo; - GetAcquireWixProperties; - _AcquireNuGetExe; - _GetInstallerProperties; - GetWixBuildConfiguration"> - <PropertyGroup> - <VSInsertionComponentName>VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion)</VSInsertionComponentName> - <NupkgOutputFile>$(ArtifactsNonShippingPackagesDir)$(VSInsertionComponentName).$(Version).nupkg</NupkgOutputFile> - - <!-- Work around NuGet silently ignoring nuspec files in PackTask by changing extension. https://github.com/NuGet/Home/issues/8637 --> - <MangledNuspecFile>$(MSBuildThisFileDirectory)vs\VS.Redist.Common.Component.nuspec.txt</MangledNuspecFile> - <VsInsertionNuspecFile>$(IntermediateOutputPath)vs\VS.Redist.Common.Component.nuspec</VsInsertionNuspecFile> - - <PackProperties /> - <PackProperties>$(PackProperties)COMPONENT_MSI=$(ComponentMsiFile);</PackProperties> - <PackProperties>$(PackProperties)ARCH=$(MsiArch);</PackProperties> - <PackProperties>$(PackProperties)COMPONENT_NAME=$(VSInsertionComponentName);</PackProperties> - <PackProperties>$(PackProperties)FRIENDLY_NAME=$(ProductBrandName);</PackProperties> - <PackProperties>$(PackProperties)PROJECT_URL=$(RepositoryUrl);</PackProperties> - - <PackArgs /> - <PackArgs>$(PackArgs) $(VsInsertionNuspecFile)</PackArgs> - <PackArgs>$(PackArgs) -Version $(Version)</PackArgs> - <PackArgs>$(PackArgs) -OutputDirectory $(ArtifactsNonShippingPackagesDir)</PackArgs> - <PackArgs>$(PackArgs) -NoDefaultExcludes</PackArgs> - <PackArgs>$(PackArgs) -NoPackageAnalysis</PackArgs> - <PackArgs>$(PackArgs) -Properties "$(PackProperties)"</PackArgs> - </PropertyGroup> - - <Copy SourceFiles="$(MangledNuspecFile)" DestinationFiles="$(VsInsertionNuspecFile)" /> - - <Exec Command="$(NuGetExeFile) pack $(PackArgs)" StandardOutputImportance="normal" /> - - <Error - Condition="!Exists('$(NupkgOutputFile)')" - Text="Failed to find VS insertion nupkg after pack command. Expected '$(NupkgOutputFile)'" /> - - <Message Text="$(MSBuildProjectName) -> $(NupkgOutputFile)" Importance="High" /> - </Target> - - <Target Name="ExtractEngineBundle" - DependsOnTargets=" - GetInstallerGenerationFlags; - GetWixBuildConfiguration"> - <Exec - Condition="'$(GenerateExeBundle)' == 'true'" - Command="insignia.exe -ib $(_OutInstallerFile) -o $(ExeBundleInstallerEngineFile)" - WorkingDirectory="$(WixToolsDir)" /> - </Target> - - <Target Name="ReattachEngineToBundle" - DependsOnTargets=" - GetInstallerGenerationFlags; - GetWixBuildConfiguration"> - <Exec - Condition="'$(GenerateExeBundle)' == 'true'" - Command="insignia.exe -ab $(ExeBundleInstallerEngineFile) $(_OutInstallerFile) -o $(_OutInstallerFile)" - WorkingDirectory="$(WixToolsDir)" /> - </Target> - - <Target Name="GetOutputWixInstallerFile" - DependsOnTargets="GetWixBuildConfiguration" - Returns="$(_OutInstallerFile)"/> - </Project> From c1042d3474aed29fba77b31f20f6c8b5324de62d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 4 Aug 2020 20:50:06 -0700 Subject: [PATCH 23/46] Factor out the archive creation targets to a Microsoft.DotNet.Build.Tasks.Archives package. --- Arcade.sln | 14 +++++++ ...crosoft.DotNet.Build.Tasks.Archives.csproj | 18 +++++++++ .../README.md | 3 ++ ...osoft.DotNet.Build.Tasks.Archives.targets} | 39 +++++++++++-------- ...Microsoft.DotNet.SharedFramework.Sdk.props | 2 - ...crosoft.DotNet.SharedFramework.Sdk.targets | 20 ++++------ .../targets/archive.props | 6 --- 7 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj create mode 100644 src/Microsoft.DotNet.Build.Tasks.Archives/README.md rename src/{Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets => Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets} (50%) delete mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props diff --git a/Arcade.sln b/Arcade.sln index 8b6db8d9fdc..1113c8e1adc 100644 --- a/Arcade.sln +++ b/Arcade.sln @@ -115,6 +115,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestProjects", "TestProject EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AttributeDifference.Contract", "src\Microsoft.DotNet.ApiCompat\tests\TestProjects\AttributeDifference\Contract\AttributeDifference.Contract.csproj", "{1CC55B23-6212-4120-BF52-8DED9CFF9FBC}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Build.Tasks.Archives", "src\Microsoft.DotNet.Build.Tasks.Archives\Microsoft.DotNet.Build.Tasks.Archives.csproj", "{5579768A-CC07-477C-ACE4-06FE9B0686A7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -709,6 +711,18 @@ Global {1CC55B23-6212-4120-BF52-8DED9CFF9FBC}.Release|x64.Build.0 = Release|Any CPU {1CC55B23-6212-4120-BF52-8DED9CFF9FBC}.Release|x86.ActiveCfg = Release|Any CPU {1CC55B23-6212-4120-BF52-8DED9CFF9FBC}.Release|x86.Build.0 = Release|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Debug|x64.ActiveCfg = Debug|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Debug|x64.Build.0 = Debug|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Debug|x86.ActiveCfg = Debug|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Debug|x86.Build.0 = Debug|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Release|Any CPU.Build.0 = Release|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Release|x64.ActiveCfg = Release|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Release|x64.Build.0 = Release|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Release|x86.ActiveCfg = Release|Any CPU + {5579768A-CC07-477C-ACE4-06FE9B0686A7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj b/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj new file mode 100644 index 00000000000..b6530723e51 --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj @@ -0,0 +1,18 @@ +<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. --> +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <TargetFrameworks>netcoreapp2.1</TargetFrameworks> + <ExcludeFromSourceBuild>false</ExcludeFromSourceBuild> + + <IsPackable>true</IsPackable> + <PackTasks>false</PackTasks> + + <Description>Common toolset for calling into CMake from MSBuild and easily reference native assets from managed projects.</Description> + <PackageType>MSBuildSdk</PackageType> + + <EnableGeneratedPackageContent>false</EnableGeneratedPackageContent> + <NoWarn>$(NoWarn);NU5105</NoWarn> + </PropertyGroup> + + <Import Project="$(RepoRoot)eng\BuildTask.targets" /> +</Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/README.md b/src/Microsoft.DotNet.Build.Tasks.Archives/README.md new file mode 100644 index 00000000000..75a163801bd --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/README.md @@ -0,0 +1,3 @@ +# Microsoft.DotNet.Build.Tasks.Archives + +Targets package for producing zip and tar archives. diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets similarity index 50% rename from src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets rename to src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets index 06ace865052..8582b9fee46 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets @@ -1,45 +1,50 @@ <Project> - <Target Name="_CreateSharedFrameworkArchive" + <PropertyGroup> + <ArchiveName Condition="'$(ArchiveName)' == ''">$([System.IO.Path]::GetFileNameWithoutExtension($(MSBuildProjectFile)))</ArchiveName> + <SymbolsArchiveName Condition="'$(SymbolsArchiveName)' == ''">$(ArchiveName)-symbols</SymbolsArchiveName> + </PropertyGroup> + + <Target Name="_CreateArchive" DependsOnTargets="_ValidatePackageInformation" Condition="'$(SkipBuild)' != 'true'"> <PropertyGroup> - <_SharedFrameworkOutputPathRoot>$(IntermediateOutputPath)sharedFramework/</_SharedFrameworkOutputPathRoot> - <_ArchiveFileName>$(SharedFrameworkArchiveName)-$(Version)</_ArchiveFileName> - <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> + <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> + <_ArchiveFileName>$(ArchiveName)-$(Version)</_ArchiveFileName> + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(ArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> </PropertyGroup> <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="PublishToDisk" - Properties="OutputPath=$(_SharedFrameworkOutputPathRoot)" /> + Properties="OutputPath=$(_OutputPathRoot)" /> <MakeDir Directories="$(PackageOutputPath)" /> - <ZipDirectory SourceDirectory="$(_SharedFrameworkOutputPathRoot)" + <ZipDirectory SourceDirectory="$(_OutputPathRoot)" Overwrite="true" DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" Condition="$([MSBuild]::IsOSPlatform(Windows))"/> - <Exec Command="tar -C '$(_SharedFrameworkOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." + <Exec Command="tar -C '$(_OutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." IgnoreExitCode="true" IgnoreStandardErrorWarningFormat="true" Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> </Target> - <Target Name="_CreateSharedFrameworkSymbolsArchive" + <Target Name="_CreateSymbolsArchive" DependsOnTargets="_ValidatePackageInformation" - Condition="'$(CreateSharedFrameworkSymbolsArchive)' == 'true' and '$(SkipBuild)' != 'true'"> + Condition="'$(CreateSymbolsArchive)' == 'true' and '$(SkipBuild)' != 'true'"> <PropertyGroup> - <_SharedFrameworkSymbolsOutputPathRoot>$(IntermediateOutputPath)sharedFrameworkSymbols/</_SharedFrameworkSymbolsOutputPathRoot> - <_ArchiveFileName>$(SharedFrameworkSymbolsArchiveName)-$(Version)</_ArchiveFileName> - <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SharedFrameworkArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> + <_SymbolsOutputPathRoot>$(IntermediateOutputPath)symbols/</_SymbolsOutputPathRoot> + <_ArchiveFileName>$(SymbolsArchiveName)-$(Version)</_ArchiveFileName> + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SymbolsArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> </PropertyGroup> <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="PublishSymbolsToDisk" - Properties="SymbolsOutputPath=$(_SharedFrameworkSymbolsOutputPathRoot)" /> + Properties="SymbolsOutputPath=$(_SymbolsOutputPathRoot)" /> <MakeDir Directories="$(PackageOutputPath)" /> - <ZipDirectory SourceDirectory="$(_SharedFrameworkSymbolsOutputPathRoot)" + <ZipDirectory SourceDirectory="$(_SymbolsOutputPathRoot)" Overwrite="true" DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" Condition="$([MSBuild]::IsOSPlatform(Windows))"/> - <Exec Command="tar -C '$(_SharedFrameworkSymbolsOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." + <Exec Command="tar -C '$(_SymbolsOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." IgnoreExitCode="true" IgnoreStandardErrorWarningFormat="true" Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> @@ -48,8 +53,8 @@ <PropertyGroup> <BuildDependsOn> $(BuildDependsOn); - _CreateSharedFrameworkArchive; - _CreateSharedFrameworkSymbolsArchive + _CreateArchive; + _CreateSymbolsArchive </BuildDependsOn> </PropertyGroup> </Project> \ No newline at end of file diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props index 21116f67fef..94f95dce251 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.props @@ -1,5 +1,3 @@ <Project> <Import Project="$(MSBuildThisFileDirectory)sharedfx.props" /> - <Import Project="$(MSBuildThisFileDirectory)archive.props" /> - <Import Project="$(MSBuildThisFileDirectory)installer.props" /> </Project> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 4397f83c0ae..27967f4227e 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -73,8 +73,8 @@ '$(PlatformPackageType)' != 'AppHostPack' and '$(PlatformPackageType)' != 'ToolPack'" Text="Unknown PlatformPackageType '$(PlatformPackageType)'" /> - <Error Condition="'$(_PackageTypeRequiresRid)' == 'true' and '$(RuntimeIdentifier)' == ''" Text="Producing a $(PlatformPackageType) requires a runtime-identifier to be specified." /> - + <Error Condition="'$(_PackageTypeRequiresRid)' == 'true' and '$(RuntimeIdentifier)' == ''" + Text="Producing a $(PlatformPackageType) requires a runtime-identifier to be specified." /> </Target> <PropertyGroup> @@ -87,35 +87,29 @@ <PropertyGroup Condition="'$(PlatformPackageType)' == 'TargetingPack'"> <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Ref</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Ref</SharedFrameworkArchiveName> + <PackageBrandNameSuffix>Targeting Pack</PackageBrandNameSuffix> <MacOSComponentNamePackType>pack.targeting</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Runtime.$(RuntimeIdentifier)</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Runtime</SharedFrameworkArchiveName> + <PackageBrandNameSuffix>Runtime</PackageBrandNameSuffix> <MacOSComponentNamePackType>sharedframework.$(SharedFrameworkName)</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup Condition="'$(PlatformPackageType)' == 'AppHostPack'"> <PackageId Condition="'$(OverridePackageId)' == ''">$(SharedFrameworkName).Host.$(RuntimeIdentifier)</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(SharedFrameworkName).Host</SharedFrameworkArchiveName> + <PackageBrandNameSuffix>AppHost Pack</PackageBrandNameSuffix> <MacOSComponentNamePackType>pack.apphost</MacOSComponentNamePackType> </PropertyGroup> <PropertyGroup> <PackageId Condition="'$(OverridePackageId)' == '' and '$(PackageId)' == ''">$(SharedFrameworkName)</PackageId> - <SharedFrameworkArchiveName Condition="'$(SharedFrameworkArchiveName)' == ''">$(PackageId)</SharedFrameworkArchiveName> <MacOSComponentNamePackType Condition="'$(MacOSComponentNamePackType)' == ''">pack.$(PlatformPackageType.ToLower())</MacOSComponentNamePackType> </PropertyGroup> - <PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.sfxproj'"> - <!-- Reset BuildDependsOn for project types we know. We update it in the following targets files. --> + <PropertyGroup> <BuildDependsOn></BuildDependsOn> </PropertyGroup> - <Import Project="$(MSBuildThisFileDirectory)sharedfx.targets" - Condition="'$(MSBuildProjectExtension)' == '.sfxproj'" /> - - <Import Project="$(MSBuildThisFileDirectory)archive.targets" - Condition="'$(GenerateArchive)' == 'true'" /> + <Import Project="$(MSBuildThisFileDirectory)sharedfx.targets" /> <Import Project="windows/wix.targets" /> </Project> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props deleted file mode 100644 index e0a1690cbf7..00000000000 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/archive.props +++ /dev/null @@ -1,6 +0,0 @@ -<Project> - <PropertyGroup> - <!-- Don't generate archives for bundles by default. --> - <GenerateArchive>true</GenerateArchive> - </PropertyGroup> -</Project> \ No newline at end of file From 61cd7160c142917e573831dcfe7a2869486d6577 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 4 Aug 2020 21:03:26 -0700 Subject: [PATCH 24/46] Fix installer package layout --- .../Microsoft.DotNet.Build.Tasks.Installers.csproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj b/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj index 5d8401ba9f9..5819c6df9ad 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj @@ -9,6 +9,8 @@ <Description>Installer task package</Description> <PackageTags>Arcade Build Tool Installer</PackageTags> <DevelopmentDependency>true</DevelopmentDependency> + <NoWarn>$(NoWarn);NU5127;NU5129</NoWarn> + <EnableDefaultNoneItems>false</EnableDefaultNoneItems> </PropertyGroup> <ItemGroup> @@ -19,6 +21,12 @@ <PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" /> </ItemGroup> + <ItemGroup> + <None Include="build/**/*.*" Pack="true"> + <PackagePath>build</PackagePath> + </None> + </ItemGroup> + <ItemGroup Condition="'$(TargetFramework)' == 'net472'"> <Compile Include="..\Common\AssemblyResolver.cs" /> <Compile Include="..\Common\BuildTask.Desktop.cs" /> From cecd7d7d3b201e6257eb09510deb5927f2d8576c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 4 Aug 2020 21:05:52 -0700 Subject: [PATCH 25/46] Fix RemoveProperties Signed-off-by: Jeremy Koritzinsky <jekoritz@microsoft.com> --- .../targets/sharedfx.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 2db62cab1f4..bd2e3ed9696 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -426,7 +426,7 @@ <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="_GetAllSharedFrameworkFiles" - RemoveProperties="SharedFrameworkOutputPath;SharedFrameworkSymbolsOutputPath"> + RemoveProperties="OutputPath;SymbolsOutputPath"> <Output TaskParameter="TargetOutputs" ItemName="_FilesToPackage" /> </MSBuild> From 5145540c35e9f722723b980ab6823eac188aab6f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 4 Aug 2020 22:25:29 -0700 Subject: [PATCH 26/46] Fix various bugs that crept in during the refactoring. Signed-off-by: Jeremy Koritzinsky <jekoritz@microsoft.com> --- ...crosoft.DotNet.Build.Tasks.Archives.csproj | 2 +- ...rosoft.DotNet.Build.Tasks.Archives.targets | 2 -- ...rosoft.DotNet.Build.Tasks.Installers.props | 7 ++++++ .../build/acquisition/Directory.Build.props | 2 -- .../build/acquisition/Directory.Build.targets | 2 -- .../build/installer.targets | 13 ++--------- .../build/windows/wix.targets | 22 +++++-------------- .../targets/sharedfx.targets | 1 + 8 files changed, 16 insertions(+), 35 deletions(-) diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj b/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj index b6530723e51..705478641d9 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj @@ -7,7 +7,7 @@ <IsPackable>true</IsPackable> <PackTasks>false</PackTasks> - <Description>Common toolset for calling into CMake from MSBuild and easily reference native assets from managed projects.</Description> + <Description>Targets for producing an archive of file outputs.</Description> <PackageType>MSBuildSdk</PackageType> <EnableGeneratedPackageContent>false</EnableGeneratedPackageContent> diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets index 8582b9fee46..76cd900839d 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets @@ -5,7 +5,6 @@ </PropertyGroup> <Target Name="_CreateArchive" - DependsOnTargets="_ValidatePackageInformation" Condition="'$(SkipBuild)' != 'true'"> <PropertyGroup> <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> @@ -28,7 +27,6 @@ </Target> <Target Name="_CreateSymbolsArchive" - DependsOnTargets="_ValidatePackageInformation" Condition="'$(CreateSymbolsArchive)' == 'true' and '$(SkipBuild)' != 'true'"> <PropertyGroup> <_SymbolsOutputPathRoot>$(IntermediateOutputPath)symbols/</_SymbolsOutputPathRoot> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props index 39d57d1b551..4232ec60bdf 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props @@ -5,4 +5,11 @@ </PropertyGroup> <UsingTask TaskName="CreateLightCommandPackageDrop" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="ExecWithRetries" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateCurrentVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateGuidFromName" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> + <UsingTask TaskName="GenerateJsonObjectString" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.props b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.props index 24643491660..6321d35eb92 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.props +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.props @@ -4,6 +4,4 @@ <Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" /> - <Import Project="$(MSBuildThisFileDirectory)..\..\sdk\Sdk.props" /> - </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets index 61c77afaf9e..fe51d7d393c 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets @@ -8,7 +8,5 @@ <GenerateInstallers>true</GenerateInstallers> </PropertyGroup> - <Import Project="$(MSBuildThisFileDirectory)..\..\sdk\Sdk.targets" /> <Import Project="$(MSBuildThisFileDirectory)..\installer.targets" Condition="'$(_InstallerTargetsImported)' != 'true'" /> - </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets index be66c83335d..591f77542bb 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets @@ -35,10 +35,6 @@ <!-- Shared targets to build installers and distro packages. --> - - <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> - <UsingTask TaskName="GenerateJsonObjectString" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> - <Import Project="$(MSBuildThisFileDirectory)windows/wix.targets" /> <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> @@ -84,13 +80,8 @@ targets that use BeforeTargets="_GetInstallerProperties". --> <Target Name="_GetInstallerProperties" - DependsOnTargets="_CalculatePackageInformation; - _GetTargetOSArchInfo; + DependsOnTargets="_GetTargetOSArchInfo; _GetProductBrandName"> - <PropertyGroup> - <InstallerName Condition="'$(InstallerName)' == ''">$(ArchiveName)</InstallerName> - </PropertyGroup> - <Error Text="InstallerName '$(InstallerName)' is empty or starts with a '-': expected a value like 'dotnet-runtime'." Condition="'$(InstallerName)' == '' or $(InstallerName.StartsWith('-'))" /> @@ -364,7 +355,7 @@ <!-- Copy files to layout. --> <PropertyGroup> - <_OutputPathRoot>$(IntermediateOutputPath)/output</_OutputPathRoot> + <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> </PropertyGroup> <MSBuild Projects="$(MSBuildProjectFullPath)" diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets index 6b66b32bda4..eae5dce9471 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets @@ -6,13 +6,6 @@ this file and switch to wixproj. See https://github.com/wixtoolset/issues/issues/5627 --> - <UsingTask TaskName="CreateLightCommandPackageDrop" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="ExecWithRetries" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="GenerateCurrentVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="GenerateGuidFromName" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <!-- Acquire WiX tools, if not present. --> @@ -131,7 +124,7 @@ <Target Name="PublishFilesForWixInstaller"> <PropertyGroup> - <FilesOutputPathRoot>$(IntermediateOutputPath)/output</FilesOutputPathRoot> + <FilesOutputPathRoot>$(IntermediateOutputPath)output/</FilesOutputPathRoot> </PropertyGroup> <MSBuild Projects="$(MSBuildProjectFullPath)" @@ -143,24 +136,19 @@ <Target Name="GetInstallerWixConfiguration" DependsOnTargets="_UseProductWixProject;PublishFilesForWixInstaller" Condition="'$(GenerateExeBundle)' != 'true'"> - - <PropertyGroup> - <OutputFilesCandleVariable Condition="'$(OutputFilesCandleVariable)' == ''">PackSrc</OutputFilesCandleVariable> - </PropertyGroup> - - <ItemGroup Condition="'$(UseCustomDirectoryHarvesting)' != 'true'"> + <ItemGroup> <DirectoryToHarvest Include="$(FilesOutputPathRoot)" Condition="'$(UseCustomDirectoryHarvesting)' != 'true'" Name="install-files" - SubstituteVar="$(OutputFilesCandleVariable)" + SubstituteVar="PackSrc" ComponentGroupName="InstallFiles" DirectoryRef="DOTNETHOME" /> <CandleVariables Include="$(OutputFilesCandleVariable)" Value="$(FilesOutputPathRoot)" - Condition="'$(UseCustomDirectoryHarvesting)' == 'true'" /> + Condition="'$(UseCustomDirectoryHarvesting)' == 'true' and '$(OutputFilesCandleVariable)' != ''" /> </ItemGroup> - <ItemGroup Condition="$(IncludeWerRelatedKeys)' == 'true'"> + <ItemGroup Condition="'$(IncludeWerRelatedKeys)' == 'true'"> <WixSrcFile Include="$(MSBuildThisFileDirectory)product/werrelatedkeys.wxs" /> <CandleVariables Include="WerRelatedKeys" Value="true" /> </ItemGroup> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index bd2e3ed9696..a009c4dfc53 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -4,6 +4,7 @@ <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <PublishReadyToRun Condition="'$(PublishReadyToRun)' == '' and '$(PlatformPackageType)' == 'RuntimePack' and '$(Configuration)' == 'Release'">true</PublishReadyToRun> <PublishReadyToRunEmitSymbols>true</PublishReadyToRunEmitSymbols> + <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings> <AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder>$(AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder);.map</AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder> </PropertyGroup> From 51caf025e1e6693c7e95c7a0af79dc810a598ebd Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 5 Aug 2020 15:15:31 -0700 Subject: [PATCH 27/46] Fix SkipBuild calculation --- .../build/bundle.targets | 2 +- .../build/installer.targets | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets index af7d94314b6..7fd80d74bde 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets @@ -1,5 +1,5 @@ <Project> - <Target Name="GetBundleGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo"> + <Target Name="GetBundleGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo;_GetInstallerSkipBuildProps" Condition="'$(SkipBuild)' != 'true'"> <Error Text="Unable to build a bundle installer for a non-Windows, non-macOS platform." Condition="'$(TargetRuntimeOS)' != 'win' and '$(TargetRuntimeOS)' != 'osx'" /> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets index 591f77542bb..799f34f19df 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets @@ -2,7 +2,7 @@ <PropertyGroup> <_InstallerTargetsImported>true</_InstallerTargetsImported> </PropertyGroup> - <Target Name="GetInstallerGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo"> + <Target Name="GetInstallerGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo;_GetInstallerSkipBuildProps"> <!-- Filter the installer generation/build flags for the current build machine. --> <PropertyGroup> <!-- From 1c1f463b64376f29a634b655de3a659e5385b1e3 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 5 Aug 2020 15:15:53 -0700 Subject: [PATCH 28/46] Fix including symbols in the symbols package. Signed-off-by: Jeremy Koritzinsky <jekoritz@microsoft.com> --- .../targets/sharedfx.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index a009c4dfc53..3986a07abc8 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -5,7 +5,7 @@ <PublishReadyToRun Condition="'$(PublishReadyToRun)' == '' and '$(PlatformPackageType)' == 'RuntimePack' and '$(Configuration)' == 'Release'">true</PublishReadyToRun> <PublishReadyToRunEmitSymbols>true</PublishReadyToRunEmitSymbols> <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings> - <AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder>$(AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder);.map</AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder> + <AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder>$(AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder);.map;.dbg;.debug;.dwarf</AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder> </PropertyGroup> <Target Name="GetSharedFrameworkFilesForReadyToRun" DependsOnTargets="$(GetSharedFrameworkFilesForReadyToRunDependsOn)" Returns="@(ReferenceCopyLocalPaths)" /> @@ -53,7 +53,7 @@ </PropertyGroup> <ItemGroup> <FilesToPackage Include="@(_r2rSymbolFiles)" Condition="Exists('%(Identity)')" IsSymbolFile="true" /> - <FilesToPackage Include="@(_r2rSymbolFilePattern)" IsSymbolFile="true" /> + <FilesToPackage Include="$(_r2rSymbolFilePattern)" IsSymbolFile="true" /> </ItemGroup> </Target> From afcb0de692069ddbe3778dc475dddf1b9692bed9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 6 Aug 2020 12:35:19 -0700 Subject: [PATCH 29/46] Invoke Pack target as an inner build instead of hooking in via a wrapper around the Build target. --- .../targets/sharedfx.targets | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 3986a07abc8..1f1905f195e 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -399,7 +399,8 @@ <Target Name="_AddFilesToNuGetPackage" BeforeTargets="_GetPackageFiles"> <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="_GetAllSharedFrameworkFiles"> + Targets="_GetAllSharedFrameworkFiles" + RemoveProperties="NoBuild"> <Output TaskParameter="TargetOutputs" ItemName="_FilesToPackage" /> </MSBuild> @@ -421,7 +422,11 @@ </ItemGroup> </Target> - <Target Name="_CreateNuGetPackage" AfterTargets="Build" DependsOnTargets="Pack" Condition="'$(SkipBuild)' != 'true'" /> + <Target Name="_CreateNuGetPackage" DependsOnTargets="_GetSkipBuildProps" Condition="'$(SkipBuild)' != 'true'"> + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="Pack" + Properties="NoBuild=true" /> + </Target> <Target Name="GetFilesToPublish"> @@ -476,4 +481,8 @@ OverwriteReadOnlyFiles="true" SkipUnchangedFiles="true" /> </Target> + + <PropertyGroup> + <BuildDependsOn>$(BuildDependsOn);_CreateNuGetPackage</BuildDependsOn> + </PropertyGroup> </Project> From f4ac87f87335f8d72c14e3f1cdb22f5c0fbe7230 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 6 Aug 2020 14:41:58 -0700 Subject: [PATCH 30/46] Clean up the skip build calculations and make them actually work. --- ...rosoft.DotNet.Build.Tasks.Archives.targets | 64 ++++++++++++++++++- ...soft.DotNet.Build.Tasks.Installers.targets | 9 +-- .../build/bundle.targets | 6 +- .../build/installer.multirid.targets | 6 +- .../build/installer.targets | 6 +- .../targets/sharedfx.targets | 4 +- 6 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets index 76cd900839d..79a69af8bc1 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets @@ -1,11 +1,70 @@ <Project> + <Target Name="_GetCurrentProjectServicingConfiguration"> + <ItemGroup> + <CurrentProjectServicingConfiguration + Include="@(ProjectServicingConfiguration)" + Condition="'%(Identity)' == '$(MSBuildProjectName)'" /> + </ItemGroup> + </Target> + + <!-- + The Microsoft build's per-package servicing policy conflicts with the source-build restrictions. + Targeting packs, for example, are only built/published when there's a known change to release. + This is in contrast to runtime packs and the shared framework, which are always built and + published. This means it's common in the Microsoft build for downstream repos to depend on two + builds' outputs: the current build's runtime assets, and some old build's targeting pack. + + The Microsoft build can simply download the old targeting pack from NuGet.org. Source-build + can't do this because the bits on NuGet.org are not built locally. Instead, source-build assumes + it's possible to use current sources to build a package with the old version. This target + applies the old build's patch version to make that happen. + + This solution has pitfalls. More info at https://github.com/dotnet/core-setup/issues/8735. The + target supports SkipSetLastReleasedVersionForSourceBuild (unused as of writing) to allow + disabling this workaround if a better way forward is implemented. + --> + <Target Name="SetLastReleasedVersionForSourceBuild" + Condition=" + '$(DotNetBuildFromSource)' == 'true' and + '$(SkipSetLastReleasedVersionForSourceBuild)' != 'true'" + BeforeTargets="GetProductVersions" + DependsOnTargets="_GetCurrentProjectServicingConfiguration"> + <PropertyGroup> + <MostRecentProducedServicingPatchVersion>%(CurrentProjectServicingConfiguration.PatchVersion)</MostRecentProducedServicingPatchVersion> + <PatchVersion Condition="'$(MostRecentProducedServicingPatchVersion)' != ''">$(MostRecentProducedServicingPatchVersion)</PatchVersion> + </PropertyGroup> + </Target> + + <Target Name="_GetSkipArchivesBuildProps" + DependsOnTargets=" + _GetCurrentProjectServicingConfiguration; + SetLastReleasedVersionForSourceBuild"> + <!-- + Skip the build if there is an applicable servicing configuration, and the servicing + configuration indicates this project shouldn't build for this patch version. + --> + <PropertyGroup Condition="'@(CurrentProjectServicingConfiguration)' != ''"> + <SkipArchivesBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipArchivesBuild> + </PropertyGroup> + + <ItemGroup> + <_TargetInstallerRuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> + </ItemGroup> + + <PropertyGroup Condition="'$(InstallerRuntimeIdentifiers)' != '' and '$(InstallerRuntimeIdentifier)' != ''"> + <!-- Avoid building a project when none of the possible InstallerRuntimeIdentifiers is the current InstallerRuntimeIdentifier. --> + <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> + <SkipArchivesBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipArchivesBuild> + </PropertyGroup> + </Target> + <PropertyGroup> <ArchiveName Condition="'$(ArchiveName)' == ''">$([System.IO.Path]::GetFileNameWithoutExtension($(MSBuildProjectFile)))</ArchiveName> <SymbolsArchiveName Condition="'$(SymbolsArchiveName)' == ''">$(ArchiveName)-symbols</SymbolsArchiveName> </PropertyGroup> <Target Name="_CreateArchive" - Condition="'$(SkipBuild)' != 'true'"> + Condition="'$(SkipArchivesBuild)' != 'true'"> <PropertyGroup> <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> <_ArchiveFileName>$(ArchiveName)-$(Version)</_ArchiveFileName> @@ -27,7 +86,7 @@ </Target> <Target Name="_CreateSymbolsArchive" - Condition="'$(CreateSymbolsArchive)' == 'true' and '$(SkipBuild)' != 'true'"> + Condition="'$(CreateSymbolsArchive)' == 'true' and '$(SkipArchivesBuild)' != 'true'"> <PropertyGroup> <_SymbolsOutputPathRoot>$(IntermediateOutputPath)symbols/</_SymbolsOutputPathRoot> <_ArchiveFileName>$(SymbolsArchiveName)-$(Version)</_ArchiveFileName> @@ -51,6 +110,7 @@ <PropertyGroup> <BuildDependsOn> $(BuildDependsOn); + _GetSkipArchivesBuildProps; _CreateArchive; _CreateSymbolsArchive </BuildDependsOn> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets index 919b86ebade..f6e58b0de79 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets @@ -35,7 +35,7 @@ </PropertyGroup> </Target> - <Target Name="_GetInstallerSkipBuildProps" + <Target Name="_GetSkipInstallerBuildProps" DependsOnTargets=" _GetCurrentProjectServicingConfiguration; SetLastReleasedVersionForSourceBuild"> @@ -44,7 +44,7 @@ configuration indicates this project shouldn't build for this patch version. --> <PropertyGroup Condition="'@(CurrentProjectServicingConfiguration)' != ''"> - <SkipBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipBuild> + <SkipInstallerBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipInstallerBuild> </PropertyGroup> <ItemGroup> @@ -54,12 +54,12 @@ <PropertyGroup Condition="'$(InstallerRuntimeIdentifiers)' != '' and '$(InstallerRuntimeIdentifier)' != ''"> <!-- Avoid building a project when none of the possible InstallerRuntimeIdentifiers is the current InstallerRuntimeIdentifier. --> <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> - <SkipBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipBuild> + <SkipInstallerBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipInstallerBuild> </PropertyGroup> </Target> <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);_GetInstallerSkipBuildProps</BuildDependsOn> + <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps</BuildDependsOn> <_GlobalPropertiesToRemoveForPublish> GenerateCrossArchMsi; GenerateMSI; @@ -139,6 +139,7 @@ </Target> <PropertyGroup> + <InstallerRuntimeIdentifiers Condition="'$(InstallerRuntimeIdentifiers)' == ''">$(RuntimeIdentifiers)</InstallerRuntimeIdentifiers> <InstallerRuntimeIdentifier Condition="'$(InstallerRuntimeIdentifier)' == ''">$(RuntimeIdentifier)</InstallerRuntimeIdentifier> </PropertyGroup> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets index 7fd80d74bde..24dddf5915d 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets @@ -1,5 +1,5 @@ <Project> - <Target Name="GetBundleGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo;_GetInstallerSkipBuildProps" Condition="'$(SkipBuild)' != 'true'"> + <Target Name="GetBundleGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo" Condition="'$(SkipInstallerBuild)' != 'true'"> <Error Text="Unable to build a bundle installer for a non-Windows, non-macOS platform." Condition="'$(TargetRuntimeOS)' != 'win' and '$(TargetRuntimeOS)' != 'osx'" /> @@ -12,7 +12,7 @@ <Import Project="$(MSBuildThisFileDirectory)windows/wix.targets" /> - <Target Name="GenerateBundles" DependsOnTargets="GetBundleGenerationFlags" Condition="'$(SkipBuild)' != 'true'"> + <Target Name="GenerateBundles" DependsOnTargets="GetBundleGenerationFlags" Condition="'$(SkipInstallerBuild)' != 'true'"> <ItemGroup> <_InstallerBuildProject Include="$(MSBuildProjectFile)" Targets="GenerateExeBundle" @@ -159,6 +159,6 @@ </Target> <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);GenerateBundles</BuildDependsOn> + <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps;GenerateBundles</BuildDependsOn> </PropertyGroup> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.multirid.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.multirid.targets index 191fcbe78d9..7ebe747f435 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.multirid.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.multirid.targets @@ -11,8 +11,8 @@ </Target> <Target Name="GenerateInstallers" - Condition="'$(SkipBuild)' != 'true'" - DependsOnTargets="_GetInstallerSkipBuildProps;_ComputeInstallerItems" + Condition="'$(SkipInstallerBuild)' != 'true'" + DependsOnTargets="_ComputeInstallerItems" Returns="@(InnerOutput)"> <Error Condition="'$(InstallerRuntimeIdentifiers)' == ''" Text="At least one RID must be specified via InstallerRuntimeIdentifiers to build installers." /> @@ -26,6 +26,6 @@ </Target> <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);GenerateInstallers</BuildDependsOn> + <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps;GenerateInstallers</BuildDependsOn> </PropertyGroup> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets index 799f34f19df..2c8a26f6aec 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets @@ -2,7 +2,7 @@ <PropertyGroup> <_InstallerTargetsImported>true</_InstallerTargetsImported> </PropertyGroup> - <Target Name="GetInstallerGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo;_GetInstallerSkipBuildProps"> + <Target Name="GetInstallerGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo"> <!-- Filter the installer generation/build flags for the current build machine. --> <PropertyGroup> <!-- @@ -37,7 +37,7 @@ --> <Import Project="$(MSBuildThisFileDirectory)windows/wix.targets" /> - <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> + <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipInstallerBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> <ItemGroup> <_InstallerBuildProject Include="$(MSBuildProjectFile)" Targets="GenerateDeb" @@ -470,6 +470,6 @@ </Target> <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);GenerateInstallers</BuildDependsOn> + <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps;GenerateInstallers</BuildDependsOn> </PropertyGroup> </Project> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 1f1905f195e..3b1bcaaa8ae 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -422,7 +422,7 @@ </ItemGroup> </Target> - <Target Name="_CreateNuGetPackage" DependsOnTargets="_GetSkipBuildProps" Condition="'$(SkipBuild)' != 'true'"> + <Target Name="_CreateNuGetPackage" Condition="'$(SkipBuild)' != 'true'"> <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Pack" Properties="NoBuild=true" /> @@ -483,6 +483,6 @@ </Target> <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);_CreateNuGetPackage</BuildDependsOn> + <BuildDependsOn>$(BuildDependsOn);_GetSkipBuildProps;_CreateNuGetPackage</BuildDependsOn> </PropertyGroup> </Project> From fe7640c28c4e965f4cb8018c18c1be63ceda2508 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 6 Aug 2020 15:18:57 -0700 Subject: [PATCH 31/46] Ensure we respect the SkipBuild property in the archives and installer packages as well. --- .../Microsoft.DotNet.Build.Tasks.Archives.targets | 13 ++++++++----- .../Microsoft.DotNet.Build.Tasks.Installers.targets | 3 +++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets index 79a69af8bc1..5146545b9f2 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets @@ -48,13 +48,16 @@ </PropertyGroup> <ItemGroup> - <_TargetInstallerRuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> + <_TargetRuntimeIdentifiers Include="$(RuntimeIdentifiers)" /> </ItemGroup> - <PropertyGroup Condition="'$(InstallerRuntimeIdentifiers)' != '' and '$(InstallerRuntimeIdentifier)' != ''"> - <!-- Avoid building a project when none of the possible InstallerRuntimeIdentifiers is the current InstallerRuntimeIdentifier. --> - <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> - <SkipArchivesBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipArchivesBuild> + <PropertyGroup Condition="'$(RuntimeIdentifiers)' != '' and '$(RuntimeIdentifier)' != ''"> + <!-- Avoid building a project when none of the possible RuntimeIdentifiers is the current RuntimeIdentifier. --> + <_RidInRidList Condition="'%(_TargetRuntimeIdentifiers.Identity)' == '$(RuntimeIdentifier)'">true</_RidInRidList> + <SkipArchivesBuild Condition="'$(_RidInRidList)' != 'true'">true</SkipArchivesBuild> + </PropertyGroup> + <PropertyGroup Condition="'$(SkipBuild)' == 'true'"> + <SkipArchivesBuild>true</SkipArchivesBuild> </PropertyGroup> </Target> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets index f6e58b0de79..9b45eec8f84 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets @@ -56,6 +56,9 @@ <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> <SkipInstallerBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipInstallerBuild> </PropertyGroup> + <PropertyGroup Condition="'$(SkipBuild)' == 'true'"> + <SkipInstallerBuild>true</SkipInstallerBuild> + </PropertyGroup> </Target> <PropertyGroup> From 82acfe3a84fc3f935e317b500ab34ccfeea04d9f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Fri, 7 Aug 2020 15:52:22 -0700 Subject: [PATCH 32/46] Don't reference desktop-only files on the .NET Core build. --- .../Microsoft.DotNet.SharedFramework.Sdk.csproj | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj index a3135bde932..d9993d9de1f 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj @@ -36,9 +36,12 @@ </ItemGroup> <ItemGroup> - <Compile Include="..\Common\AssemblyResolver.cs" Link="src\AssemblyResolver.cs" /> <Compile Include="..\Common\BuildTask.cs" Link="src\BuildTask.cs" /> - <Compile Include="..\Common\BuildTask.Desktop.cs" Link="src\BuildTask.Desktop.cs" /> + </ItemGroup> + + <ItemGroup Condition="'$(TargetFramework)' == 'net472'"> + <Compile Include="..\Common\AssemblyResolver.cs" /> + <Compile Include="..\Common\BuildTask.Desktop.cs" /> </ItemGroup> <Import Project="$(RepoRoot)eng\BuildTask.targets" /> From 8b63d86f125c7368e3cfb6b28bb5a9fafdf20b9d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 20 Aug 2020 11:59:45 -0700 Subject: [PATCH 33/46] Update READMEs of the three packages to reflect the updated organization. --- .../README.md | 9 ++ .../README.md | 89 ++++++++++++++++++- .../README.md | 84 +---------------- 3 files changed, 99 insertions(+), 83 deletions(-) diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/README.md b/src/Microsoft.DotNet.Build.Tasks.Archives/README.md index 75a163801bd..e85298c3091 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Archives/README.md +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/README.md @@ -1,3 +1,12 @@ # Microsoft.DotNet.Build.Tasks.Archives Targets package for producing zip and tar archives. + +This package generates an archive that can be extracted on top of an existing .NET SDK or Runtime layout. The name of this file is derived from the `ArchiveName` property and the RID. The `ArchiveName` property defaults to the project file name without the extension. This package calls the `PublishToDisk` target on the project to generate the project layout. + +## Build Skip Support for Unsupported Platforms and Servicing + +This SDK also supports automatically skipping builds on unsupported platforms or in servicing releases. If a project with a list of provided RIDs in `RuntimeIdentifiers` is built with the `RuntimeIdentifier` property set to a RID that is not in the `RuntimeIdentifiers` list, the build will be skipped. This enables cleanly skipping optional packs, installers, or bundles that only exist on specific platforms. + +Additionally, if a `ProjectServicingConfiguration` item is provided with the identity of the project name and the `PatchVersion` metadata on the item is not equal to the current `PatchVersion`, the build will be skipped. This support enables a repository to disable building targeting packs in servicing releases if that is desired. + diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/README.md b/src/Microsoft.DotNet.Build.Tasks.Installers/README.md index a5162d18379..0df8082eb06 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/README.md +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/README.md @@ -1,6 +1,93 @@ # Microsoft.DotNet.Build.Tasks.Installers -Task package for installer specific tasks. Currently contains: +Task package for installer specific tasks with optional opt-in targets for automatic installer generation. + +This package supports generating installers for projects in .msi, .deb, .rpm, and .pkg formats. This support is opt-in by setting the `GenerateInstallers` property to `true`. In addition, to enable the .deb and .rpm support, the `GenerateDebPackage` and `GenerateRpmPackage` properties respectively need to be set to true. This support depends on a `PublishToDisk` target that publishes the project's outputs to the `$(OutputPath)` folder. + +There are a few common properties used by all of the installer types and the bundle installers (documented after the installers): + +- `InstallerName` + - The name of the installer file without an extension.. +- `ProductBrandPrefix` + - The branding name of this component, such as "Microsoft Windows Desktop" +- `PackageBrandNameSuffix` (`ToolPack` installers only) + - The type of package, for example "Shared Host" or "AppHost Pack". This is set automatically for any non-ToolPack package types. + +For correct branding and versioning, this SDK has a dependency on Arcade's versioning setup, including the `MajorVersion`, `MinorVersion`, `PreReleaseVersionLabel`, `PreReleaseVersionIteration` and `DotNetFinalVersionKind` properties. + +Since some framework packs do not use `RuntimeIdentifier`s in their build, for example targeting packs, for the installer build you can define `InstallerRuntimeIdentifiers` and the build will fan out for the installer build across those target RIDs. In addition, the `InstallerRuntimeIdentifier` property will default to the value of `RuntimeIdentifier` if it is not set. + +### Wix MSI configuration + +If you have files that need to have a stabilized identity in the MSI file, you can add items to the `HeatOutputFileElementToStabilize` item group. Each item in this group specifies a unique suffix of a path (enough to identify a single file) and a value for the `ReplacementId` metadata as the id to set in the MSI for this file. + +If you want to create MSIs for the target RID that target other architecture install locations, you can add `CrossArchSdkMsiInstallerArch` items for all of the target architecture install locations you want to generate installers of the current build for. + +### Linux package configuration + +To add package dependencies for linux packages, add a `LinuxPackageDependency` item with the version in the `Version` metadata. + +#### Deb package configuration + +To add additional properties for the deb package tool, add items to the `DebJsonProperty` item group. + +#### Rpm package configuration + +To add additional properties for the deb package tool, add items to the `RpmJsonProperty` item group. + +### MacOS Pkg configuration + +To specify a directory where `pkgbuild` should look for scripts, set the `MacOSScriptsDirectory` to the path to the scripts. + +If you are building a `ToolPack` pack, you need to specify the `MacOSComponentNamePackType` property to create the component name for the `.pkg` package. If you want the component name to not include the version (for example you are building the shared host), you can set the `IncludeVersionInMacOSComponentName` property to false. + +If your `pkg` is later going to be bundled in a macOS `pkg` bundle created by `productbuild`, you should also specify the `MacOSPackageDescription` property, which will set the package description in the bundle distribution file. + +### Visual Studio Insertion Package configuration + +Visual Studio insertion packages generated by the SDK are named in the form `VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion)` + +The `InstallerTargetArchitecture` and later properties are automatically calculated by the SDK or are version properties. You are required to provide the `VSInsertionShortComponentName` property value yourself. + +## Building Installer Bundles + +As part of the installer support, the SDK supports building Wix bundle installers and macOS pkg bundles. These bundles are defined in a separate project with a `.bundleproj` extension that includes the .NET SDK and this SDK as shown in the example project. Like the installer targets, the bundle targets also use the `InstallerName` property and the support for `RuntimeIdentifiers` to identify target architectures for the bundle. The bundle targets verify that the RID is targeting an OS that supports an installer bundle, so be sure to limit the RID list to platforms that support bundles (Windows and macOS today). + +The bundle installers also require the `ProductBrandPrefix` property and a `BundleNameSuffix` property in the place of the `PackageBrandNameSuffix` property used by the installer targets. + +To include installers in the bundle, add `BundleComponentReference` items that point to the projects that produce the installers. + +### Wix Bundle configuration + +A number of properties are required to configure the Wix bundle generation: + +- `BundleInstallerUpgradeCodeSeed` + - This property specifies a seed for generating the bundle upgrade GUID. This must not change within a product band, otherwise the upgrade code will not match. +- `BundleThemeDirectory` + - This property should point to a directory that contains the following files and folders: + - `bundle.thm` + - `bundle.wxl` + - A `theme` directory that contains subdirectories with resources per codepage. + +### MacOS Pkg bundle configuration + +A number of properties are required to configure the MacOS Pkg bundle generation: + +- `MacOSBundleIdentifierName` + - The identifier of the pkg bundle. +- `MacOSBundleResourcesPath` + - The folder with the resources for the bundle, including various HTML and RTF files that the installer shows the user. +- `MacOSBundleTemplate` + - A partial [macOS Distribution XML file](https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html). The build system will add the `<title>`, `<choices-outline>`, `<choice>`, and `<pkg-ref>` elements automatically to the provided XML file based on the provided properties and the bundled `.pkg` files defined in the project file. + +## Build Skip Support for Unsupported Platforms and Servicing + +This SDK also supports automatically skipping builds on unsupported platforms or in servicing releases. If a project with a list of provided RIDs in `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` is built with the `RuntimeIdentifier` property or `InstallerRuntimeIdentifier` property set to a RID that is not in the `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` list respectively, the build will be skipped. This enables cleanly skipping optional packs, installers, or bundles that only exist on specific platforms. + +Additionally, if a `ProjectServicingConfiguration` item is provided with the identity of the project name and the `PatchVersion` metadata on the item is not equal to the current `PatchVersion`, the build will be skipped. This support enables a repository to disable building targeting packs in servicing releases if that is desired. + +## Tasks + - **CreateLightCommandPackageDrop** - Create a layout that can be used to re-execute a light command. This can be used during post-build signing after files have been replaced. A cmd file that can be used to reconstruct the installer is created. diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md index 047a7d5fc84..46ff72cffc3 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md @@ -141,90 +141,10 @@ By default, this SDK also generates an archive that can be extracted on top of a ### Custom dumping to disk -This SDK provides a custom target named `PublishSharedFrameworkToDisk` that publishes the generated framework pack to disk as though the folder specified via the `SharedFrameworkOutputPath` is the root of a .NET SDK or Runtime layout. This target is used internally by the archive and installer generation. Additionally, if you are defining a custom installer project that doesn't use the `.sfxproj` extension (for example if you only need installers and not NuGet packages), you can define your own `PublishSharedFrameworkToDisk` target that publishes your files to disk in the correct layout for the installers to place files in during installation. - -## Building Installers - -In addition to producing framework packs this SDK also supports generating installers for the shared framework in .msi, .deb, .rpm, and .pkg formats. This support is opt-in by setting the `GenerateInstallers` property to `true`. In addition, to enable the .deb and .rpm support, the `GenerateDebPackage` and `GenerateRpmPackage` properties respectively need to be set to true. This support acts independently of the shared framework support and only depends on the `PublishSharedFrameworkToDisk` target. So, you can use the SDK with a project that has a non-`.sfxproj` extension such as `.proj` or `.installproj` and set `GenerateInstallers` to `true` to opt into only installer generation, as long as you define the `PublishSharedFrameworkToDisk` target. - -There are a few common properties used by all of the installer types and the bundle installers (documented after the installers): - -- `SharedFrameworkInstallerName` - - The name of the installer file without an extension. This defaults to `SharedFrameworkArchiveName`. -- `ProductBrandPrefix` - - The branding name of this component, such as "Microsoft Windows Desktop" -- `PackageBrandNameSuffix` (`ToolPack` installers only) - - The type of package, for example "Shared Host" or "AppHost Pack". This is set automatically for any non-ToolPack package types. - -For correct branding and versioning, this SDK has a dependency on Arcade's versioning setup, including the `MajorVersion`, `MinorVersion`, `PreReleaseVersionLabel`, `PreReleaseVersionIteration` and `DotNetFinalVersionKind` properties. - -Since some framework packs do not use `RuntimeIdentifier`s in their build, for example targeting packs, for the installer build you can define `InstallerRuntimeIdentifiers` and the build will fan out for the installer build across those target RIDs. In addition, the `InstallerRuntimeIdentifier` property will default to the value of `RuntimeIdentifier` if it is not set. - -### Wix MSI configuration - -If you have files that need to have a stabilized identity in the MSI file, you can add items to the `HeatOutputFileElementToStabilize` item group. Each item in this group specifies a unique suffix of a path (enough to identify a single file) and a value for the `ReplacementId` metadata as the id to set in the MSI for this file. - -If you want to create MSIs for the target RID that target other architecture install locations, you can add `CrossArchSdkMsiInstallerArch` items for all of the target architecture install locations you want to generate installers of the current build for. - -### Linux package configuration - -To add package dependencies for linux packages, add a `LinuxPackageDependency` item with the version in the `Version` metadata. - -#### Deb package configuration - -To add additional properties for the deb package tool, add items to the `DebJsonProperty` item group. - -#### Rpm package configuration - -To add additional properties for the deb package tool, add items to the `RpmJsonProperty` item group. - -### MacOS Pkg configuration - -To specify a directory where `pkgbuild` should look for scripts, set the `MacOSScriptsDirectory` to the path to the scripts. - -If you are building a `ToolPack` pack, you need to specify the `MacOSComponentNamePackType` property to create the component name for the `.pkg` package. If you want the component name to not include the version (for example you are building the shared host), you can set the `IncludeVersionInMacOSComponentName` property to false. - -If your `pkg` is later going to be bundled in a macOS `pkg` bundle created by `productbuild`, you should also specify the `MacOSPackageDescription` property, which will set the package description in the bundle distribution file. - -### Visual Studio Insertion Package configuration - -Visual Studio insertion packages generated by the SDK are named in the form `VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion)` - -The `InstallerTargetArchitecture` and later properties are automatically calculated by the SDK or are version properties. You are required to provide the `VSInsertionShortComponentName` property value yourself. - -## Building Installer Bundles - -As part of the installer support, the SDK supports building Wix bundle installers and macOS pkg bundles. These bundles are defined in a separate project with a `.bundleproj` extension that includes the .NET SDK and this SDK as shown in the example project. Like the installer targets, the bundle targets also use the `SharedFrameworkName` and `SharedFrameworkInstallerName` properties, as well as the support for `RuntimeIdentifiers` to identify target architectures for the bundle. The bundle targets verify that the RID is targeting an OS that supports an installer bundle, so be sure to limit the RID list to platforms that support bundles (Windows and macOS today). - -The bundle installers also require the `ProductBrandPrefix` property and a `BundleNameSuffix` property in the place of the `PackageBrandNameSuffix` property used by the installer targets. - -To include installers in the bundle, add `BundleComponentReference` items that point to the projects that produce the installers. - -### Wix Bundle configuration - -A number of properties are required to configure the Wix bundle generation: - -- `BundleInstallerUpgradeCodeSeed` - - This property specifies a seed for generating the bundle upgrade GUID. This must not change within a product band, otherwise the upgrade code will not match. -- `BundleThemeDirectory` - - This property should point to a directory that contains the following files and folders: - - `bundle.thm` - - `bundle.wxl` - - A `theme` directory that contains subdirectories with resources per codepage. - -### MacOS Pkg bundle configuration - -A number of properties are required to configure the MacOS Pkg bundle generation: - -- `MacOSBundleIdentifierName` - - The identifier of the pkg bundle. -- `MacOSBundleResourcesPath` - - The folder with the resources for the bundle, including various HTML and RTF files that the installer shows the user. -- `MacOSBundleTemplate` - - A partial [macOS Distribution XML file](https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html). The build system will add the `<title>`, `<choices-outline>`, `<choice>`, and `<pkg-ref>` elements automatically to the provided XML file based on the provided properties and the bundled `.pkg` files defined in the project file. +This SDK provides a custom target named `PublishToDisk` that publishes the generated framework pack to disk as though the folder specified via the `OutputPath` is the root of a .NET SDK or Runtime layout. This target is provided for compatibilty with the `Microsoft.DotNet.Build.Tasks.Installers` and `Microsoft.DotNet.Build.Tasks.Archives` packages, but can also be used to implement custom dumping to disk to set up test harnesses with the shared framework. ## Build Skip Support for Unsupported Platforms and Servicing -This SDK also supports automatically skipping builds on unsupported platforms or in servicing releases. If a project with a list of provided RIDs in `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` is built with the `RuntimeIdentifier` property or `InstallerRuntimeIdentifier` property set to a RID that is not in the `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` list respectively, the build will be skipped. This enables cleanly skipping optional packs, installers, or bundles that only exist on specific platforms. +This SDK also supports automatically skipping builds on unsupported platforms or in servicing releases. If a project with a list of provided RIDs in `RuntimeIdentifiers` is built with the `RuntimeIdentifier` property set to a RID that is not in the `RuntimeIdentifiers` list, the build will be skipped. This enables cleanly skipping optional packs, installers, or bundles that only exist on specific platforms. Additionally, if a `ProjectServicingConfiguration` item is provided with the identity of the project name and the `PatchVersion` metadata on the item is not equal to the current `PatchVersion`, the build will be skipped. This support enables a repository to disable building targeting packs in servicing releases if that is desired. From 2da6aecbfb6b2219a7dde742ad985b58b13d80bf Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 20 Aug 2020 12:23:37 -0700 Subject: [PATCH 34/46] Enable overriding host json file location in the package (for crossgen2). --- .../Microsoft.DotNet.SharedFramework.Sdk.targets | 2 +- .../targets/sharedfx.targets | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 27967f4227e..800fd890fd0 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -67,7 +67,7 @@ </PropertyGroup> </Target> - <Target Name="_ValidatePackageInformation"> + <Target Name="_CalculatePackageInformation"> <Error Condition="'$(PlatformPackageType)' != 'TargetingPack' and '$(PlatformPackageType)' != 'RuntimePack' and '$(PlatformPackageType)' != 'AppHostPack' and diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 3b1bcaaa8ae..dd776960589 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -6,6 +6,7 @@ <PublishReadyToRunEmitSymbols>true</PublishReadyToRunEmitSymbols> <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings> <AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder>$(AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder);.map;.dbg;.debug;.dwarf</AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder> + <HostJsonTargetPath Condition="'$(HostJsonTargetPath)' == ''">runtimes/$(RuntimeIdentifier)/lib/$(TargetFramework)</HostJsonTargetPath> </PropertyGroup> <Target Name="GetSharedFrameworkFilesForReadyToRun" DependsOnTargets="$(GetSharedFrameworkFilesForReadyToRunDependsOn)" Returns="@(ReferenceCopyLocalPaths)" /> @@ -28,7 +29,7 @@ </Target> <Target Name="_PrepareSharedFrameworkForReadyToRun" - DependsOnTargets="_ValidatePackageInformation; + DependsOnTargets="_CalculatePackageInformation; GetSharedFrameworkFilesForReadyToRun" Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <ItemGroup> @@ -58,7 +59,7 @@ </Target> <Target Name="GetFilesToPackage" - DependsOnTargets="_ValidatePackageInformation; + DependsOnTargets="_CalculatePackageInformation; ResolveFrameworkReferences; ResolveLockFileCopyLocalFiles; ResolveReferences; @@ -149,7 +150,7 @@ </GenerateSharedFrameworkDepsFile> <ItemGroup> <_SharedFrameworkDepsFile> - <TargetPath>runtimes/$(RuntimeIdentifier)/lib/$(TargetFramework)</TargetPath> + <TargetPath>$(HostJsonTargetPath)</TargetPath> <GeneratedBuildFile>true</GeneratedBuildFile> </_SharedFrameworkDepsFile> <FileWrites Include="@(_SharedFrameworkDepsFile)" /> @@ -171,7 +172,7 @@ Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <ItemGroup> <FilesToPackage Include="$(ProjectRuntimeConfigFilePath)" - TargetPath="runtimes/$(RuntimeIdentifier)/lib/$(TargetFramework)" + TargetPath="$(HostJsonTargetPath)" GeneratedBuildFile="true" /> </ItemGroup> </Target> @@ -270,7 +271,7 @@ --> <UsingTask TaskName="GeneratePlatformManifestEntriesFromFileList" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> <Target Name="_GeneratePlatformManifestFromRuntimePack" - DependsOnTargets="_ValidatePackageInformation" + DependsOnTargets="_CalculatePackageInformation" Condition="'$(PlatformPackageType)' == 'TargetingPack' and '$(UseTemplatedPlatformManifest)' != 'true'"> <PropertyGroup> @@ -386,7 +387,8 @@ </Target> <Target Name="_GetAllSharedFrameworkFiles" - DependsOnTargets="GetFilesToPackage; + DependsOnTargets="_CalculatePackageInformation; + GetFilesToPackage; _GenerateSharedFrameworkDepsFile; _GenerateSharedFrameworkRuntimeConfigFile; _ValidateAllFilesInTemplatedPlatformManifest; From bf6c57bfec0972b635f1a835fb86b12045acdbae Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Fri, 21 Aug 2020 16:58:23 -0700 Subject: [PATCH 35/46] Implement closure, type, and file version validation. --- ...icrosoft.DotNet.SharedFramework.Sdk.csproj | 6 + .../src/Packaging/Extensions.cs | 32 ++++ .../src/ValidateFileVersions.cs | 138 ++++++++++++++++++ .../targets/sharedfx.targets | 54 ++++++- 4 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs create mode 100644 src/Microsoft.DotNet.SharedFramework.Sdk/src/ValidateFileVersions.cs diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj index d9993d9de1f..c00379a435b 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/Microsoft.DotNet.SharedFramework.Sdk.csproj @@ -24,6 +24,7 @@ <PackageReference Include="NuGet.Packaging" Version="$(NuGetVersion)" /> <PackageReference Include="NuGet.ProjectModel" Version="$(NuGetVersion)" /> <PackageReference Include="NuGet.Versioning" Version="$(NuGetVersion)" /> + <PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" /> </ItemGroup> <ItemGroup> @@ -38,6 +39,11 @@ <ItemGroup> <Compile Include="..\Common\BuildTask.cs" Link="src\BuildTask.cs" /> </ItemGroup> + + <ItemGroup> + <Compile Include="..\Microsoft.DotNet.Build.Tasks.Packaging\src\VerifyClosure.cs" Link="src/Packaging/VerifyClosure.cs" /> + <Compile Include="..\Microsoft.DotNet.Build.Tasks.Packaging\src\VerifyTypes.cs" Link="src/Packaging/VerifyTypes.cs" /> + </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net472'"> <Compile Include="..\Common\AssemblyResolver.cs" /> diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs new file mode 100644 index 00000000000..f9ced7d4a9d --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using NuGet; +using NuGet.Frameworks; +using NuGet.Versioning; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.Versioning; + +namespace Microsoft.DotNet.Build.Tasks.Packaging +{ + public static class Extensions + { + public static IEnumerable<T> NullAsEmpty<T>(this IEnumerable<T> source) + { + if (source == null) + { + return Enumerable.Empty<T>(); + } + + return source; + } + } +} + diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/ValidateFileVersions.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/ValidateFileVersions.cs new file mode 100644 index 00000000000..7942a4bb7be --- /dev/null +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/ValidateFileVersions.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Construction; +using Microsoft.Build.Framework; +using Microsoft.DotNet.Build.Tasks; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Microsoft.DotNet.SharedFramework.Sdk +{ + public class ValidateFileVersions : BuildTask + { + private static readonly Version ZeroVersion = new Version(0, 0, 0, 0); + + [Required] + public ITaskItem[] Files { get; set; } + + public override bool Execute() + { + var fileVersions = new Dictionary<string, FileVersionData>(StringComparer.OrdinalIgnoreCase); + foreach(var file in Files) + { + if (file.GetMetadata("IsSymbolFile").Equals("true", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + var fileName = Path.GetFileName(file.ItemSpec); + + var current = GetFileVersionData(file); + + FileVersionData existing; + + if (fileVersions.TryGetValue(fileName, out existing)) + { + if (current.AssemblyVersion != null) + { + if (existing.AssemblyVersion == null) + { + fileVersions[fileName] = current; + continue; + } + else if (current.AssemblyVersion != existing.AssemblyVersion) + { + if (current.AssemblyVersion > existing.AssemblyVersion) + { + fileVersions[fileName] = current; + } + continue; + } + } + + if (current.FileVersion != null && + existing.FileVersion != null) + { + if (current.FileVersion > existing.FileVersion) + { + fileVersions[fileName] = current; + } + } + } + else + { + fileVersions[fileName] = current; + } + } + + // Check for versionless files after all duplicate filenames are resolved, rather than + // logging errors immediately upon encountering a versionless file. There may be + // duplicate filenames where only one has a version, and this is ok. The highest version + // is used. + var versionlessFiles = fileVersions + .Where(p => + p.Key.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || + p.Key.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + .Where(p => (p.Value.FileVersion ?? ZeroVersion) == ZeroVersion) + .Select(p => p.Value.File.ItemSpec) + .ToArray(); + + if (versionlessFiles.Any()) + { + Log.LogError( + $"Missing FileVersion in {versionlessFiles.Length} shared framework files:" + + string.Concat(versionlessFiles.Select(f => Environment.NewLine + f))); + } + + return !Log.HasLoggedErrors; + } + + FileVersionData GetFileVersionData(ITaskItem file) + { + var filePath = file.GetMetadata("FullPath"); + + if (File.Exists(filePath)) + { + return new FileVersionData() + { + AssemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version, + FileVersion = FileUtilities.GetFileVersion(filePath), + File = file + }; + } + else + { + // allow for the item to specify version directly + Version assemblyVersion, fileVersion; + + Version.TryParse(file.GetMetadata("AssemblyVersion"), out assemblyVersion); + Version.TryParse(file.GetMetadata("FileVersion"), out fileVersion); + + if (fileVersion == null) + { + // FileVersionInfo will return 0.0.0.0 if a file doesn't have a version. + // match that behavior + fileVersion = ZeroVersion; + } + + return new FileVersionData() + { + AssemblyVersion = assemblyVersion, + FileVersion = fileVersion, + File = file + }; + } + } + + class FileVersionData + { + public Version AssemblyVersion { get; set; } + public Version FileVersion { get; set; } + public ITaskItem File { get; set; } + } + } +} diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index dd776960589..4407d295535 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -386,6 +386,55 @@ </ItemGroup> </Target> + <UsingTask TaskName="VerifyClosure" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> + <Target Name="_VerifyClosure" + DependsOnTargets="GetFilesToPackage" + Condition="'$(SkipValidatePackage)' != 'true'"> + <ItemGroup> + <_closureFiles Include="@(FilesToPackage)" Condition="'%(Extension)' == '.dll' or '%(Extension)' == '$(LibraryFileExtension)'" /> + <_closureFileNames Include="@(_closureFiles->'%(FileName)')" Original="%(Identity)" /> + + <_closureFileNamesFiltered Include="@(_closureFileNames)" Exclude="@(ExcludeFromClosure)"/> + <_closureFileFiltered Include="@(_closureFileNamesFiltered->'%(Original)')"/> + </ItemGroup> + + <Message Text="Verifying closure of $(PackageId) assemblies" /> + <VerifyClosure + Sources="@(_closureFileFiltered)" + IgnoredReferences="@(IgnoredReference)" + DependencyGraphFilePath="$(IntermediateOutputPath)assembly-graph.dgml" /> + </Target> + + <UsingTask TaskName="VerifyTypes" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> + <Target Name="_VerifyNoDuplicateTypes" + DependsOnTargets="GetFilesToPackage" + Condition="'$(SkipValidatePackage)' != 'true'"> + + <ItemGroup> + <_dupTypeFiles Include="@(FilesToPackage)" Condition="'%(Extension)' == '.dll' or '%(Extension)' == '$(LibraryFileExtension)'" /> + <_dupTypeFileName Include="@(_dupTypeFiles->'%(FileName)')" Original="%(Identity)" /> + + <_dupTypeFileNamesFiltered Include="@(_dupTypeFileName)" Exclude="@(ExcludeFromDuplicateTypes)"/> + <_dupTypeFileFiltered Include="@(_dupTypeFileNamesFiltered->'%(Original)')"/> + </ItemGroup> + + <Message Text="Verifying no duplicate types in $(PackageId) assemblies" /> + <VerifyTypes + Sources="@(_dupTypeFileFiltered)" + IgnoredTypes="@(IgnoredDuplicateType)" /> + </Target> + + <UsingTask TaskName="ValidateFileVersions" AssemblyFile="$(DotNetSharedFrameworkTaskFile)" /> + <Target Name="_ValidateFileVersions" + DependsOnTargets="GetFilesToPackage" + Condition="'$(PermitDllAndExeFilesLackingFileVersion)' != 'true' and '$(PlatformPackageType)' == 'RuntimePack'"> + <ItemGroup> + <_filesToVerify Include="@(FilesToPackage)" Condition="'%(Extension)' == '.dll' or '%(Extension)' == '.exe'" /> + </ItemGroup> + <ValidateFileVersions Files="@(_filesToVerify)" /> + </Target> + + <Target Name="_GetAllSharedFrameworkFiles" DependsOnTargets="_CalculatePackageInformation; GetFilesToPackage; @@ -395,7 +444,10 @@ _CreatePlatformManifest; _GenerateFrameworkList; _AddPackageOverridesToPackage; - _CreateVersionsFile" + _CreateVersionsFile; + _VerifyClosure; + _VerifyNoDuplicateTypes; + _ValidateFileVersions" Returns="@(FilesToPackage)" /> <Target Name="_AddFilesToNuGetPackage" BeforeTargets="_GetPackageFiles"> From bd6a7e3f6ff03eae22dac450a743c1a5cbc20870 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Mon, 24 Aug 2020 11:20:11 -0700 Subject: [PATCH 36/46] PR feedback. --- ...rosoft.DotNet.Build.Tasks.Installers.props | 6 +-- .../build/installer.targets | 54 ++++++++++--------- .../README.md | 24 ++++----- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props index 4232ec60bdf..68aaa900e8a 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props @@ -4,12 +4,12 @@ <MicrosoftDotNetBuildTasksInstallersTaskAssembly Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tools\net472\Microsoft.DotNet.Build.Tasks.Installers.dll</MicrosoftDotNetBuildTasksInstallersTaskAssembly> </PropertyGroup> + <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> <UsingTask TaskName="CreateLightCommandPackageDrop" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> <UsingTask TaskName="ExecWithRetries" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> <UsingTask TaskName="GenerateCurrentVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> <UsingTask TaskName="GenerateGuidFromName" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> <UsingTask TaskName="GenerateJsonObjectString" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> + <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets index 2c8a26f6aec..05ed82f5f4b 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets @@ -39,30 +39,36 @@ <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipInstallerBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> <ItemGroup> - <_InstallerBuildProject Include="$(MSBuildProjectFile)" - Targets="GenerateDeb" - Properties="GenerateDeb=true" - Condition="'$(GenerateDeb)' == 'true'" /> - <_InstallerBuildProject Include="$(MSBuildProjectFile)" - Targets="GenerateRpm" - Properties="GenerateRpm=true" - Condition="'$(GenerateRpm)' == 'true'" /> - <_InstallerBuildProject Include="$(MSBuildProjectFile)" - Targets="GenerateMsi" - Properties="GenerateMSI=true" - Condition="'$(GenerateMSI)' == 'true'" /> - <_InstallerBuildProject Include="$(MSBuildProjectFile)" - Targets="GenerateCrossArchMsi" - Properties="GenerateCrossArchMsi=true" - Condition="'$(GenerateCrossArchMsi)' == 'true'" /> - <_InstallerBuildProject Include="$(MSBuildProjectFile)" - Targets="GeneratePkg" - Properties="GeneratePkg=true" - Condition="'$(GeneratePkg)' == 'true'" /> - <_InstallerBuildProject Include="$(MSBuildProjectFile)" - Targets="GenerateVSInsertionNupkg" - Properties="GenerateMSI=$(GenerateMSI);GenerateCrossArchMsi=$(GenerateCrossArchMsi)" - Condition="'$(GenerateVSInsertionPackages)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateDeb" + Properties="GenerateDeb=true" + Condition="'$(GenerateDeb)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateRpm" + Properties="GenerateRpm=true" + Condition="'$(GenerateRpm)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateMsi" + Properties="GenerateMSI=true" + Condition="'$(GenerateMSI)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateCrossArchMsi" + Properties="GenerateCrossArchMsi=true" + Condition="'$(GenerateCrossArchMsi)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GeneratePkg" + Properties="GeneratePkg=true" + Condition="'$(GeneratePkg)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateVSInsertionNupkg" + Properties="GenerateMSI=$(GenerateMSI);GenerateCrossArchMsi=$(GenerateCrossArchMsi)" + Condition="'$(GenerateVSInsertionPackages)' == 'true'" /> </ItemGroup> <MSBuild Projects="@(_InstallerBuildProject)" Targets="%(_InstallerBuildProject.Targets)" diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md index 46ff72cffc3..ed2931fba1a 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/README.md +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/README.md @@ -70,6 +70,7 @@ Cons of harvesting: Pros of templating: - All files can be declared to be in the manifest without needing every file on disk. + - As a result, this enables building a targeting pack for a runtime pack that has disjoint sets of files on different RIDs, such as Microsoft.NETCore.App, without needing to download any runtime pack builds. - Targeting pack can be built independently of the runtime pack. - Ensures that every file in a runtime pack is a known file in the manifest. @@ -81,25 +82,17 @@ Cons of templating: ### Platform Manifest Harvesting -For platforms where all target platforms have the same files -or where one platform has a superset of the files available -on all platforms, we can generate a platform manifest from -the present files in the runtime pack. +For platforms where all target platforms have the same files or where one platform has a superset of the files available on all platforms, we can generate a platform manifest from the present files in the runtime pack. This is enabled by default or when `UseTemplatedPlatformManifest` is not set to `true`. Set the `RuntimePackProjectPath` to the path to the runtime pack shared framework project. -If you only want to use one RID to generate the platform manifest, you can set -the `RuntimePackPlatformForManifest` property to the RID you'd like to use. -If the chosen RID doesn't have a superset of files for all shipping platforms, -then you may have unexpected behavior when using the produced targeting pack. +If you only want to use one RID to generate the platform manifest, you can set the `RuntimePackPlatformForManifest` property to the RID you'd like to use. If the chosen RID doesn't have a superset of files for all shipping platforms, then you may have unexpected behavior when using the produced targeting pack. ### Templated Platform Manifest -For shared frameworks with differing sets of files on various platforms -and with no single platform that contains all of the files, this SDK provides support -for creating a platform manifest from a templated list of items. +For shared frameworks with differing sets of files on various platforms and with no single platform that contains all of the files, this SDK provides support for creating a platform manifest from a templated list of items. Assumptions: @@ -107,7 +100,7 @@ Assumptions: or have an easily calculatable assembly version and file version. - All native files have an easily calculatable file version. -To use, set `UseTemplatedPlatformManifes`t to true and define a set of `PlatformManifestFileEntry` items +To use, set `UseTemplatedPlatformManifest` to true and define a set of `PlatformManifestFileEntry` items `PlatformManifestFileEntry` metadata: @@ -121,9 +114,10 @@ To use, set `UseTemplatedPlatformManifes`t to true and define a set of `Platform - A file version for this file if it is not present in the ref-pack build. Properties for these targets: -`UseTemplatedPlatformManifest`: Set to true to enable the templated platform manifest generation -`PlatformManifestFallbackAssemblyVersion`: Fallback asssembly version when one is needed and there is no fallback on the entry. -`PlatformManifestFallbackFileVersion`: Fallback file version when one is needed and there is no fallback on the entry. + +- `UseTemplatedPlatformManifest`: Set to true to enable the templated platform manifest generation +- `PlatformManifestFallbackAssemblyVersion`: Fallback asssembly version when one is needed and there is no fallback on the entry. +- `PlatformManifestFallbackFileVersion`: Fallback file version when one is needed and there is no fallback on the entry. ### RuntimeList/FrameworkList Generation From 304f6671f996fb153e5440e808256b3be1205005 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Mon, 24 Aug 2020 11:33:46 -0700 Subject: [PATCH 37/46] Comments and var clarification. --- .../src/GenerateSharedFrameworkDepsFile.cs | 8 ++++---- .../src/Packaging/Extensions.cs | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs index 50b0b1f9304..bbb38d2b1c1 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/GenerateSharedFrameworkDepsFile.cs @@ -54,10 +54,10 @@ public override bool Execute() { continue; } - var filePath = file.ItemSpec; - var fileName = Path.GetFileName(filePath); - var fileVersion = FileUtilities.GetFileVersion(filePath)?.ToString() ?? string.Empty; - var assemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version; + string filePath = file.ItemSpec; + string fileName = Path.GetFileName(filePath); + string fileVersion = FileUtilities.GetFileVersion(filePath)?.ToString() ?? string.Empty; + Version assemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version; string cultureMaybe = file.GetMetadata("Culture"); if (!string.IsNullOrEmpty(cultureMaybe)) { diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs index f9ced7d4a9d..f8da82b1198 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/Packaging/Extensions.cs @@ -14,6 +14,11 @@ using System.Reflection; using System.Runtime.Versioning; +// This file implements a subset of the Extensions class in the +// Microsoft.DotNet.Build.Tasks.Packaging project to support +// the Shared Framework SDK's usage of the VerifyClosure and +// VerifyTypes tasks used in shared framework validation. + namespace Microsoft.DotNet.Build.Tasks.Packaging { public static class Extensions From 840626ff5ad6df69fc2f6b3127986be6f628e923 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Wed, 26 Aug 2020 17:29:24 -0700 Subject: [PATCH 38/46] Automatically calculate ignored references for closure validation based on the referenced framework packs. Exclude culture assemblies from closure validation (otherwise we get duplicate assembly names). --- .../targets/sharedfx.targets | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 4407d295535..0735c3aeef7 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -391,13 +391,23 @@ DependsOnTargets="GetFilesToPackage" Condition="'$(SkipValidatePackage)' != 'true'"> <ItemGroup> - <_closureFiles Include="@(FilesToPackage)" Condition="'%(Extension)' == '.dll' or '%(Extension)' == '$(LibraryFileExtension)'" /> + <_closureFiles + Include="@(FilesToPackage)" + Condition="('%(Extension)' == '.dll' or '%(Extension)' == '$(LibraryFileExtension)') and '%(FilesToPackage.Culture)' == ''" /> <_closureFileNames Include="@(_closureFiles->'%(FileName)')" Original="%(Identity)" /> <_closureFileNamesFiltered Include="@(_closureFileNames)" Exclude="@(ExcludeFromClosure)"/> <_closureFileFiltered Include="@(_closureFileNamesFiltered->'%(Original)')"/> </ItemGroup> + <ItemGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> + <IgnoredReference Include="@(RuntimePackAsset->'%(FileName)')" /> + </ItemGroup> + + <ItemGroup Condition="'$(PlatformPackageType)' == 'TargetingPack'"> + <IgnoredReference Include="@(Reference->'%(FileName)')" Condition="'%(Reference.FrameworkReferenceName)' != ''" /> + </ItemGroup> + <Message Text="Verifying closure of $(PackageId) assemblies" /> <VerifyClosure Sources="@(_closureFileFiltered)" @@ -411,7 +421,9 @@ Condition="'$(SkipValidatePackage)' != 'true'"> <ItemGroup> - <_dupTypeFiles Include="@(FilesToPackage)" Condition="'%(Extension)' == '.dll' or '%(Extension)' == '$(LibraryFileExtension)'" /> + <_dupTypeFiles + Include="@(FilesToPackage)" + Condition="('%(Extension)' == '.dll' or '%(Extension)' == '$(LibraryFileExtension)') and '%(FilesToPackage.Culture)' == ''" /> <_dupTypeFileName Include="@(_dupTypeFiles->'%(FileName)')" Original="%(Identity)" /> <_dupTypeFileNamesFiltered Include="@(_dupTypeFileName)" Exclude="@(ExcludeFromDuplicateTypes)"/> From 80aee3c5e617e0c1010c82143156e4ff9dcbd235 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 27 Aug 2020 11:24:20 -0700 Subject: [PATCH 39/46] Set SelfContained to true when processing framework references. --- .../targets/sharedfx.targets | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 0735c3aeef7..24055e12d12 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -9,6 +9,24 @@ <HostJsonTargetPath Condition="'$(HostJsonTargetPath)' == ''">runtimes/$(RuntimeIdentifier)/lib/$(TargetFramework)</HostJsonTargetPath> </PropertyGroup> + + <!-- + Enable Self-Contained for FrameworkReference resolution to enable resolving runtime pack assets. + (used in package verification) + --> + <Target Name="_ConsiderSelfContainedForFrameworkReferenceResolution" BeforeTargets="ProcessFrameworkReferences"> + <PropertyGroup> + <SelfContained>true</SelfContained> + </PropertyGroup> + </Target> + + + <Target Name="_RemoveSelfContainedAfterFrameworkReferenceResolution" AfterTargets="ProcessFrameworkReferences"> + <PropertyGroup> + <SelfContained>true</SelfContained> + </PropertyGroup> + </Target> + <Target Name="GetSharedFrameworkFilesForReadyToRun" DependsOnTargets="$(GetSharedFrameworkFilesForReadyToRunDependsOn)" Returns="@(ReferenceCopyLocalPaths)" /> <ItemDefinitionGroup> From a5c17c4212664bf4e89b583c25b0703642a1462d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Thu, 27 Aug 2020 11:29:15 -0700 Subject: [PATCH 40/46] Don't set BuildDependsOn to empty. It breaks packages that hook into it (like the installers and archives packages) Signed-off-by: Jeremy Koritzinsky <jekoritz@microsoft.com> --- .../targets/Microsoft.DotNet.SharedFramework.Sdk.targets | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets index 800fd890fd0..bb6f43f9004 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/Microsoft.DotNet.SharedFramework.Sdk.targets @@ -105,10 +105,6 @@ <MacOSComponentNamePackType Condition="'$(MacOSComponentNamePackType)' == ''">pack.$(PlatformPackageType.ToLower())</MacOSComponentNamePackType> </PropertyGroup> - <PropertyGroup> - <BuildDependsOn></BuildDependsOn> - </PropertyGroup> - <Import Project="$(MSBuildThisFileDirectory)sharedfx.targets" /> <Import Project="windows/wix.targets" /> From 93e05772f98d0cf628f1f3ab37ce9c749065b988 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Mon, 14 Sep 2020 17:23:28 -0700 Subject: [PATCH 41/46] Use System.Reflection.Metadata to get the assembly name to ensure .NETFX compat. Use more efficient publicKeyToken-to-string algorithm. --- .../src/CreateFrameworkListFile.cs | 12 ++++++++--- .../src/FileUtilities.cs | 21 ++++++++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs index 61e15002906..8e46d1f9449 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/CreateFrameworkListFile.cs @@ -6,8 +6,10 @@ using Microsoft.DotNet.Build.Tasks; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; +using System.Text; using System.Xml.Linq; namespace Microsoft.DotNet.SharedFramework.Sdk @@ -142,9 +144,13 @@ public override bool Execute() if (publicKeyToken != null) { - publicKeyTokenHex = BitConverter.ToString(publicKeyToken) - .ToLowerInvariant() - .Replace("-", ""); + int len = publicKeyToken.Length; + StringBuilder publicKeyTokenBuilder = new StringBuilder(len * 2); + for (int i = 0; i < len; i++) + { + publicKeyTokenBuilder.Append(publicKeyToken[i].ToString("x", CultureInfo.InvariantCulture)); + } + publicKeyTokenHex = publicKeyTokenBuilder.ToString(); } else { diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs b/src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs index 035c2ba2348..97ab8b182c8 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/src/FileUtilities.cs @@ -7,6 +7,8 @@ using System.Diagnostics; using System.IO; using System.Reflection; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; namespace Microsoft.DotNet.SharedFramework.Sdk { @@ -37,13 +39,30 @@ public static AssemblyName GetAssemblyName(string path) try { - return AssemblyName.GetAssemblyName(path); + using (var stream = File.OpenRead(path)) + using (var peReader = new PEReader(stream)) + { + if (peReader.HasMetadata) + { + return peReader.GetMetadataReader().GetAssemblyDefinition().GetAssemblyName(); + } + } } catch (BadImageFormatException) { // Not a valid assembly. return null; } + return null; } } + + internal struct AssemblyInformation + { + public string SimpleName { get; set; } + + public Version Version { get; set; } + + public string PublicKeyToken { get; set; } + } } From 47b10a6fa9efbbfd2369367fc9998253f02d7eba Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 15 Sep 2020 10:57:31 -0700 Subject: [PATCH 42/46] Rename folder to avoid warning --- .../Microsoft.DotNet.Build.Tasks.Installers.csproj | 2 +- .../build/bundle.targets | 2 +- .../build/installer.targets | 2 +- .../build/{windows => wix}/bundle/bundle.wxs | 0 .../build/{windows => wix}/bundle/dummyEula.rtf | 0 .../build/{windows => wix}/eula.rtf | 0 .../build/{windows => wix}/product/breadcrumbstorefolder.wxs | 0 .../build/{windows => wix}/product/product.common.wxi | 0 .../build/{windows => wix}/product/product.wxs | 0 .../build/{windows => wix}/product/provider.wxs | 0 .../build/{windows => wix}/product/registrykeys.wxs | 0 .../build/{windows => wix}/product/werrelatedkeys.wxs | 0 .../build/{windows => wix}/variables.wxi | 0 .../{windows => wix}/vs/VS.Redist.Common.Component.nuspec.txt | 0 .../build/{windows => wix}/wix.targets | 0 15 files changed, 3 insertions(+), 3 deletions(-) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/bundle/bundle.wxs (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/bundle/dummyEula.rtf (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/eula.rtf (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/product/breadcrumbstorefolder.wxs (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/product/product.common.wxi (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/product/product.wxs (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/product/provider.wxs (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/product/registrykeys.wxs (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/product/werrelatedkeys.wxs (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/variables.wxi (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/vs/VS.Redist.Common.Component.nuspec.txt (100%) rename src/Microsoft.DotNet.Build.Tasks.Installers/build/{windows => wix}/wix.targets (100%) diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj b/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj index c15f358af79..152dd84b8c3 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/Microsoft.DotNet.Build.Tasks.Installers.csproj @@ -9,7 +9,7 @@ <Description>Installer task package</Description> <PackageTags>Arcade Build Tool Installer</PackageTags> <DevelopmentDependency>true</DevelopmentDependency> - <NoWarn>$(NoWarn);NU5127;NU5129</NoWarn> + <NoWarn>$(NoWarn);NU5127</NoWarn> <EnableDefaultNoneItems>false</EnableDefaultNoneItems> </PropertyGroup> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets index 24dddf5915d..cc51f13f22d 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets @@ -10,7 +10,7 @@ </PropertyGroup> </Target> - <Import Project="$(MSBuildThisFileDirectory)windows/wix.targets" /> + <Import Project="$(MSBuildThisFileDirectory)wix/wix.targets" /> <Target Name="GenerateBundles" DependsOnTargets="GetBundleGenerationFlags" Condition="'$(SkipInstallerBuild)' != 'true'"> <ItemGroup> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets index 05ed82f5f4b..28d2ca9574d 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets @@ -35,7 +35,7 @@ <!-- Shared targets to build installers and distro packages. --> - <Import Project="$(MSBuildThisFileDirectory)windows/wix.targets" /> + <Import Project="$(MSBuildThisFileDirectory)wix/wix.targets" /> <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipInstallerBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> <ItemGroup> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/bundle.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/bundle/bundle.wxs similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/bundle.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/bundle/bundle.wxs diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/dummyEula.rtf b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/bundle/dummyEula.rtf similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/bundle/dummyEula.rtf rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/bundle/dummyEula.rtf diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/eula.rtf b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/eula.rtf similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/eula.rtf rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/eula.rtf diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/breadcrumbstorefolder.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/breadcrumbstorefolder.wxs similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/breadcrumbstorefolder.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/breadcrumbstorefolder.wxs diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.common.wxi b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/product.common.wxi similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.common.wxi rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/product.common.wxi diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/product.wxs similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/product.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/product.wxs diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/provider.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/provider.wxs similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/provider.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/provider.wxs diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/registrykeys.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/registrykeys.wxs similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/registrykeys.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/registrykeys.wxs diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/werrelatedkeys.wxs b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/werrelatedkeys.wxs similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/product/werrelatedkeys.wxs rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/product/werrelatedkeys.wxs diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/variables.wxi b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/variables.wxi similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/variables.wxi rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/variables.wxi diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/vs/VS.Redist.Common.Component.nuspec.txt b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/vs/VS.Redist.Common.Component.nuspec.txt similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/vs/VS.Redist.Common.Component.nuspec.txt rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/vs/VS.Redist.Common.Component.nuspec.txt diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/wix.targets similarity index 100% rename from src/Microsoft.DotNet.Build.Tasks.Installers/build/windows/wix.targets rename to src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/wix.targets From a46fcafe38a7a0c61b3bf57f68aa6ef458b1ad45 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 15 Sep 2020 10:58:45 -0700 Subject: [PATCH 43/46] Remove unneeded NoWarn Signed-off-by: Jeremy Koritzinsky <jekoritz@microsoft.com> --- .../Microsoft.DotNet.Build.Tasks.Archives.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj b/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj index 705478641d9..5b3de6dc143 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/Microsoft.DotNet.Build.Tasks.Archives.csproj @@ -11,7 +11,6 @@ <PackageType>MSBuildSdk</PackageType> <EnableGeneratedPackageContent>false</EnableGeneratedPackageContent> - <NoWarn>$(NoWarn);NU5105</NoWarn> </PropertyGroup> <Import Project="$(RepoRoot)eng\BuildTask.targets" /> From 6ece97262be3ab067798fa69cd3e2febbf8d37cd Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 15 Sep 2020 15:51:28 -0700 Subject: [PATCH 44/46] React to changes in PrepareForReadyToRunCompilation. SDK version 5.0.0-dev.20465.2 --- .../targets/sharedfx.targets | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets index 24055e12d12..6018e76a05a 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets @@ -54,12 +54,21 @@ <ResolvedFileToPublish Include="@(RuntimePackAsset)" ReferenceOnly="true" PostprocessAssembly="true" RelativePath="%(FileName)%(Extension)" /> <ResolvedFileToPublish Include="@(ReferenceCopyLocalPaths)" Exclude="@(RuntimePackAsset)" PostprocessAssembly="true" RelativePath="%(FileName)%(Extension)" /> </ItemGroup> + <!-- + The PrepareForReadyToRunCompilation task now requires the MainAssembly metadata to be set. + It's only used in composite mode, which we do not use, so create a ficticous $(PackageId).dll + to ensure we don't accidentally trigger any unexpected behavior. + --> + <ItemGroup Condition="'@(IntermediateAssembly)' == ''"> + <IntermediateAssembly Include="$(IntermediateOutputPath)/$(PackageId).dll" /> + </ItemGroup> </Target> <Target Name="_ReadyToRunSharedFramework" DependsOnTargets="_PrepareSharedFrameworkForReadyToRun;CreateReadyToRunImages" Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <ItemGroup> + <IntermediateAssembly Remove="@(IntermediateAssembly)" /> <FilesToPackage Remove="@(FilesToPackage)" /> <FilesToPackage Include="@(ResolvedFileToPublish)" Exclude="@(RuntimePackAsset)" /> <FilesToPackage Condition="'%(FilesToPackage.AssetType)' == 'native'" IsNative="true" /> From 97010716d896b001c7815800169579182e8812bc Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 15 Sep 2020 16:40:30 -0700 Subject: [PATCH 45/46] Fix packaging non RuntimePack shared framework packs in msi installers. SDK version 5.0.0-dev.20465.3 --- .../targets/windows/wix.targets | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets index 3d899ba7b89..1142b02a14d 100644 --- a/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets +++ b/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets @@ -2,11 +2,9 @@ <Target Name="_GetFrameworkPackWixConfiguration" BeforeTargets="GetInstallerWixConfiguration" DependsOnTargets="PublishFilesForWixInstaller"> - <PropertyGroup> - <UseCustomDirectoryHarvesting>true</UseCustomDirectoryHarvesting> - </PropertyGroup> <PropertyGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> <WixIncludeRegistryKeys>true</WixIncludeRegistryKeys> + <UseCustomDirectoryHarvesting>true</UseCustomDirectoryHarvesting> </PropertyGroup> <ItemGroup Condition="'$(PlatformPackageType)' == 'RuntimePack'"> From 70819f2a99f6d717fdc8a82a4c3a8b3f0a56248f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky <jekoritz@microsoft.com> Date: Tue, 29 Sep 2020 11:00:22 -0700 Subject: [PATCH 46/46] Enable overriding the targets and tasks for the installer and archives packages like the old system for Microsoft.DotNet.Build.Tasks.SharedFramework. --- ...rosoft.DotNet.Build.Tasks.Archives.targets | 118 +--- .../build/archives.targets | 121 ++++ ...rosoft.DotNet.Build.Tasks.Installers.props | 10 +- ...soft.DotNet.Build.Tasks.Installers.targets | 154 +---- .../build/acquisition/Directory.Build.targets | 2 +- .../build/installer.props | 9 + .../build/installer.singlerid.targets | 481 +++++++++++++++ .../build/installer.targets | 556 ++++-------------- 8 files changed, 732 insertions(+), 719 deletions(-) create mode 100644 src/Microsoft.DotNet.Build.Tasks.Archives/build/archives.targets create mode 100644 src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.singlerid.targets diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets index 5146545b9f2..3378424536a 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/build/Microsoft.DotNet.Build.Tasks.Archives.targets @@ -1,121 +1,7 @@ <Project> - <Target Name="_GetCurrentProjectServicingConfiguration"> - <ItemGroup> - <CurrentProjectServicingConfiguration - Include="@(ProjectServicingConfiguration)" - Condition="'%(Identity)' == '$(MSBuildProjectName)'" /> - </ItemGroup> - </Target> - - <!-- - The Microsoft build's per-package servicing policy conflicts with the source-build restrictions. - Targeting packs, for example, are only built/published when there's a known change to release. - This is in contrast to runtime packs and the shared framework, which are always built and - published. This means it's common in the Microsoft build for downstream repos to depend on two - builds' outputs: the current build's runtime assets, and some old build's targeting pack. - - The Microsoft build can simply download the old targeting pack from NuGet.org. Source-build - can't do this because the bits on NuGet.org are not built locally. Instead, source-build assumes - it's possible to use current sources to build a package with the old version. This target - applies the old build's patch version to make that happen. - - This solution has pitfalls. More info at https://github.com/dotnet/core-setup/issues/8735. The - target supports SkipSetLastReleasedVersionForSourceBuild (unused as of writing) to allow - disabling this workaround if a better way forward is implemented. - --> - <Target Name="SetLastReleasedVersionForSourceBuild" - Condition=" - '$(DotNetBuildFromSource)' == 'true' and - '$(SkipSetLastReleasedVersionForSourceBuild)' != 'true'" - BeforeTargets="GetProductVersions" - DependsOnTargets="_GetCurrentProjectServicingConfiguration"> - <PropertyGroup> - <MostRecentProducedServicingPatchVersion>%(CurrentProjectServicingConfiguration.PatchVersion)</MostRecentProducedServicingPatchVersion> - <PatchVersion Condition="'$(MostRecentProducedServicingPatchVersion)' != ''">$(MostRecentProducedServicingPatchVersion)</PatchVersion> - </PropertyGroup> - </Target> - - <Target Name="_GetSkipArchivesBuildProps" - DependsOnTargets=" - _GetCurrentProjectServicingConfiguration; - SetLastReleasedVersionForSourceBuild"> - <!-- - Skip the build if there is an applicable servicing configuration, and the servicing - configuration indicates this project shouldn't build for this patch version. - --> - <PropertyGroup Condition="'@(CurrentProjectServicingConfiguration)' != ''"> - <SkipArchivesBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipArchivesBuild> - </PropertyGroup> - - <ItemGroup> - <_TargetRuntimeIdentifiers Include="$(RuntimeIdentifiers)" /> - </ItemGroup> - - <PropertyGroup Condition="'$(RuntimeIdentifiers)' != '' and '$(RuntimeIdentifier)' != ''"> - <!-- Avoid building a project when none of the possible RuntimeIdentifiers is the current RuntimeIdentifier. --> - <_RidInRidList Condition="'%(_TargetRuntimeIdentifiers.Identity)' == '$(RuntimeIdentifier)'">true</_RidInRidList> - <SkipArchivesBuild Condition="'$(_RidInRidList)' != 'true'">true</SkipArchivesBuild> - </PropertyGroup> - <PropertyGroup Condition="'$(SkipBuild)' == 'true'"> - <SkipArchivesBuild>true</SkipArchivesBuild> - </PropertyGroup> - </Target> - <PropertyGroup> - <ArchiveName Condition="'$(ArchiveName)' == ''">$([System.IO.Path]::GetFileNameWithoutExtension($(MSBuildProjectFile)))</ArchiveName> - <SymbolsArchiveName Condition="'$(SymbolsArchiveName)' == ''">$(ArchiveName)-symbols</SymbolsArchiveName> + <MicrosoftDotNetBuildTasksArchivesMSBuildDir Condition="'$(MicrosoftDotNetBuildTasksArchivesMSBuildDir)' == ''">$(MSBuildThisFileDirectory)</MicrosoftDotNetBuildTasksArchivesMSBuildDir> </PropertyGroup> - <Target Name="_CreateArchive" - Condition="'$(SkipArchivesBuild)' != 'true'"> - <PropertyGroup> - <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> - <_ArchiveFileName>$(ArchiveName)-$(Version)</_ArchiveFileName> - <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(ArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> - </PropertyGroup> - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishToDisk" - Properties="OutputPath=$(_OutputPathRoot)" /> - - <MakeDir Directories="$(PackageOutputPath)" /> - <ZipDirectory SourceDirectory="$(_OutputPathRoot)" - Overwrite="true" - DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" - Condition="$([MSBuild]::IsOSPlatform(Windows))"/> - <Exec Command="tar -C '$(_OutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." - IgnoreExitCode="true" - IgnoreStandardErrorWarningFormat="true" - Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> - </Target> - - <Target Name="_CreateSymbolsArchive" - Condition="'$(CreateSymbolsArchive)' == 'true' and '$(SkipArchivesBuild)' != 'true'"> - <PropertyGroup> - <_SymbolsOutputPathRoot>$(IntermediateOutputPath)symbols/</_SymbolsOutputPathRoot> - <_ArchiveFileName>$(SymbolsArchiveName)-$(Version)</_ArchiveFileName> - <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SymbolsArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> - </PropertyGroup> - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishSymbolsToDisk" - Properties="SymbolsOutputPath=$(_SymbolsOutputPathRoot)" /> - - <MakeDir Directories="$(PackageOutputPath)" /> - <ZipDirectory SourceDirectory="$(_SymbolsOutputPathRoot)" - Overwrite="true" - DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" - Condition="$([MSBuild]::IsOSPlatform(Windows))"/> - <Exec Command="tar -C '$(_SymbolsOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." - IgnoreExitCode="true" - IgnoreStandardErrorWarningFormat="true" - Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> - </Target> - - <PropertyGroup> - <BuildDependsOn> - $(BuildDependsOn); - _GetSkipArchivesBuildProps; - _CreateArchive; - _CreateSymbolsArchive - </BuildDependsOn> - </PropertyGroup> + <Import Project="$(MicrosoftDotNetBuildTasksArchivesMSBuildDir)archives.targets" /> </Project> \ No newline at end of file diff --git a/src/Microsoft.DotNet.Build.Tasks.Archives/build/archives.targets b/src/Microsoft.DotNet.Build.Tasks.Archives/build/archives.targets new file mode 100644 index 00000000000..5146545b9f2 --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Archives/build/archives.targets @@ -0,0 +1,121 @@ +<Project> + <Target Name="_GetCurrentProjectServicingConfiguration"> + <ItemGroup> + <CurrentProjectServicingConfiguration + Include="@(ProjectServicingConfiguration)" + Condition="'%(Identity)' == '$(MSBuildProjectName)'" /> + </ItemGroup> + </Target> + + <!-- + The Microsoft build's per-package servicing policy conflicts with the source-build restrictions. + Targeting packs, for example, are only built/published when there's a known change to release. + This is in contrast to runtime packs and the shared framework, which are always built and + published. This means it's common in the Microsoft build for downstream repos to depend on two + builds' outputs: the current build's runtime assets, and some old build's targeting pack. + + The Microsoft build can simply download the old targeting pack from NuGet.org. Source-build + can't do this because the bits on NuGet.org are not built locally. Instead, source-build assumes + it's possible to use current sources to build a package with the old version. This target + applies the old build's patch version to make that happen. + + This solution has pitfalls. More info at https://github.com/dotnet/core-setup/issues/8735. The + target supports SkipSetLastReleasedVersionForSourceBuild (unused as of writing) to allow + disabling this workaround if a better way forward is implemented. + --> + <Target Name="SetLastReleasedVersionForSourceBuild" + Condition=" + '$(DotNetBuildFromSource)' == 'true' and + '$(SkipSetLastReleasedVersionForSourceBuild)' != 'true'" + BeforeTargets="GetProductVersions" + DependsOnTargets="_GetCurrentProjectServicingConfiguration"> + <PropertyGroup> + <MostRecentProducedServicingPatchVersion>%(CurrentProjectServicingConfiguration.PatchVersion)</MostRecentProducedServicingPatchVersion> + <PatchVersion Condition="'$(MostRecentProducedServicingPatchVersion)' != ''">$(MostRecentProducedServicingPatchVersion)</PatchVersion> + </PropertyGroup> + </Target> + + <Target Name="_GetSkipArchivesBuildProps" + DependsOnTargets=" + _GetCurrentProjectServicingConfiguration; + SetLastReleasedVersionForSourceBuild"> + <!-- + Skip the build if there is an applicable servicing configuration, and the servicing + configuration indicates this project shouldn't build for this patch version. + --> + <PropertyGroup Condition="'@(CurrentProjectServicingConfiguration)' != ''"> + <SkipArchivesBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipArchivesBuild> + </PropertyGroup> + + <ItemGroup> + <_TargetRuntimeIdentifiers Include="$(RuntimeIdentifiers)" /> + </ItemGroup> + + <PropertyGroup Condition="'$(RuntimeIdentifiers)' != '' and '$(RuntimeIdentifier)' != ''"> + <!-- Avoid building a project when none of the possible RuntimeIdentifiers is the current RuntimeIdentifier. --> + <_RidInRidList Condition="'%(_TargetRuntimeIdentifiers.Identity)' == '$(RuntimeIdentifier)'">true</_RidInRidList> + <SkipArchivesBuild Condition="'$(_RidInRidList)' != 'true'">true</SkipArchivesBuild> + </PropertyGroup> + <PropertyGroup Condition="'$(SkipBuild)' == 'true'"> + <SkipArchivesBuild>true</SkipArchivesBuild> + </PropertyGroup> + </Target> + + <PropertyGroup> + <ArchiveName Condition="'$(ArchiveName)' == ''">$([System.IO.Path]::GetFileNameWithoutExtension($(MSBuildProjectFile)))</ArchiveName> + <SymbolsArchiveName Condition="'$(SymbolsArchiveName)' == ''">$(ArchiveName)-symbols</SymbolsArchiveName> + </PropertyGroup> + + <Target Name="_CreateArchive" + Condition="'$(SkipArchivesBuild)' != 'true'"> + <PropertyGroup> + <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> + <_ArchiveFileName>$(ArchiveName)-$(Version)</_ArchiveFileName> + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(ArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> + </PropertyGroup> + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishToDisk" + Properties="OutputPath=$(_OutputPathRoot)" /> + + <MakeDir Directories="$(PackageOutputPath)" /> + <ZipDirectory SourceDirectory="$(_OutputPathRoot)" + Overwrite="true" + DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" + Condition="$([MSBuild]::IsOSPlatform(Windows))"/> + <Exec Command="tar -C '$(_OutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." + IgnoreExitCode="true" + IgnoreStandardErrorWarningFormat="true" + Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> + </Target> + + <Target Name="_CreateSymbolsArchive" + Condition="'$(CreateSymbolsArchive)' == 'true' and '$(SkipArchivesBuild)' != 'true'"> + <PropertyGroup> + <_SymbolsOutputPathRoot>$(IntermediateOutputPath)symbols/</_SymbolsOutputPathRoot> + <_ArchiveFileName>$(SymbolsArchiveName)-$(Version)</_ArchiveFileName> + <_ArchiveFileName Condition="'$(RuntimeIdentifier)' != ''">$(SymbolsArchiveName)-$(RuntimeIdentifier)-$(Version)</_ArchiveFileName> + </PropertyGroup> + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishSymbolsToDisk" + Properties="SymbolsOutputPath=$(_SymbolsOutputPathRoot)" /> + + <MakeDir Directories="$(PackageOutputPath)" /> + <ZipDirectory SourceDirectory="$(_SymbolsOutputPathRoot)" + Overwrite="true" + DestinationFile="$(PackageOutputPath)/$(_ArchiveFileName).zip" + Condition="$([MSBuild]::IsOSPlatform(Windows))"/> + <Exec Command="tar -C '$(_SymbolsOutputPathRoot)' -czf $(PackageOutputPath)/$(_ArchiveFileName).tar.gz ." + IgnoreExitCode="true" + IgnoreStandardErrorWarningFormat="true" + Condition="!$([MSBuild]::IsOSPlatform(Windows))"/> + </Target> + + <PropertyGroup> + <BuildDependsOn> + $(BuildDependsOn); + _GetSkipArchivesBuildProps; + _CreateArchive; + _CreateSymbolsArchive + </BuildDependsOn> + </PropertyGroup> +</Project> \ No newline at end of file diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props index 68aaa900e8a..86072785333 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.props @@ -2,14 +2,8 @@ <PropertyGroup> <MicrosoftDotNetBuildTasksInstallersTaskAssembly Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildThisFileDirectory)..\tools\netcoreapp2.0\Microsoft.DotNet.Build.Tasks.Installers.dll</MicrosoftDotNetBuildTasksInstallersTaskAssembly> <MicrosoftDotNetBuildTasksInstallersTaskAssembly Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tools\net472\Microsoft.DotNet.Build.Tasks.Installers.dll</MicrosoftDotNetBuildTasksInstallersTaskAssembly> + <MicrosoftDotNetBuildTasksInstallersMSBuildDir Condition="'$(MicrosoftDotNetBuildTasksInstallersMSBuildDir)' == ''">$(MSBuildThisFileDirectory)</MicrosoftDotNetBuildTasksInstallersMSBuildDir> </PropertyGroup> - <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> - <UsingTask TaskName="CreateLightCommandPackageDrop" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="ExecWithRetries" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="GenerateCurrentVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="GenerateGuidFromName" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="GenerateJsonObjectString" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> - <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> - <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <Import Project="$(MicrosoftDotNetBuildTasksInstallersMSBuildDir)installer.props" /> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets index 9b45eec8f84..1d307053518 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/Microsoft.DotNet.Build.Tasks.Installers.targets @@ -1,155 +1,3 @@ <Project> - <Target Name="_GetCurrentProjectServicingConfiguration"> - <ItemGroup> - <CurrentProjectServicingConfiguration - Include="@(ProjectServicingConfiguration)" - Condition="'%(Identity)' == '$(MSBuildProjectName)'" /> - </ItemGroup> - </Target> - - <!-- - The Microsoft build's per-package servicing policy conflicts with the source-build restrictions. - Targeting packs, for example, are only built/published when there's a known change to release. - This is in contrast to runtime packs and the shared framework, which are always built and - published. This means it's common in the Microsoft build for downstream repos to depend on two - builds' outputs: the current build's runtime assets, and some old build's targeting pack. - - The Microsoft build can simply download the old targeting pack from NuGet.org. Source-build - can't do this because the bits on NuGet.org are not built locally. Instead, source-build assumes - it's possible to use current sources to build a package with the old version. This target - applies the old build's patch version to make that happen. - - This solution has pitfalls. More info at https://github.com/dotnet/core-setup/issues/8735. The - target supports SkipSetLastReleasedVersionForSourceBuild (unused as of writing) to allow - disabling this workaround if a better way forward is implemented. - --> - <Target Name="SetLastReleasedVersionForSourceBuild" - Condition=" - '$(DotNetBuildFromSource)' == 'true' and - '$(SkipSetLastReleasedVersionForSourceBuild)' != 'true'" - BeforeTargets="GetProductVersions" - DependsOnTargets="_GetCurrentProjectServicingConfiguration"> - <PropertyGroup> - <MostRecentProducedServicingPatchVersion>%(CurrentProjectServicingConfiguration.PatchVersion)</MostRecentProducedServicingPatchVersion> - <PatchVersion Condition="'$(MostRecentProducedServicingPatchVersion)' != ''">$(MostRecentProducedServicingPatchVersion)</PatchVersion> - </PropertyGroup> - </Target> - - <Target Name="_GetSkipInstallerBuildProps" - DependsOnTargets=" - _GetCurrentProjectServicingConfiguration; - SetLastReleasedVersionForSourceBuild"> - <!-- - Skip the build if there is an applicable servicing configuration, and the servicing - configuration indicates this project shouldn't build for this patch version. - --> - <PropertyGroup Condition="'@(CurrentProjectServicingConfiguration)' != ''"> - <SkipInstallerBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipInstallerBuild> - </PropertyGroup> - - <ItemGroup> - <_TargetInstallerRuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> - </ItemGroup> - - <PropertyGroup Condition="'$(InstallerRuntimeIdentifiers)' != '' and '$(InstallerRuntimeIdentifier)' != ''"> - <!-- Avoid building a project when none of the possible InstallerRuntimeIdentifiers is the current InstallerRuntimeIdentifier. --> - <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> - <SkipInstallerBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipInstallerBuild> - </PropertyGroup> - <PropertyGroup Condition="'$(SkipBuild)' == 'true'"> - <SkipInstallerBuild>true</SkipInstallerBuild> - </PropertyGroup> - </Target> - - <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps</BuildDependsOn> - <_GlobalPropertiesToRemoveForPublish> - GenerateCrossArchMsi; - GenerateMSI; - GeneratePkg; - GenerateDeb; - GenerateRpm; - IsShipping; - ComponentMsiFile; - InstallerRuntimeIdentifier; - InstallerTargetArchitecture; - CrossArchContentsArch - </_GlobalPropertiesToRemoveForPublish> - </PropertyGroup> - - <ItemGroup> - <_GlobalPropertiesToRemoveForPublish Include="$(_GlobalPropertiesToRemoveForPublish)" /> - </ItemGroup> - - <Target Name="_GetTargetOSArchInfo"> - <Error Condition="'$(InstallerRuntimeIdentifier)' == ''" - Text="An InstallerRuntimeIdentifier must be specified when building installers." /> - <PropertyGroup> - <TargetRuntimeOS>$(InstallerRuntimeIdentifier.Substring(0, $(InstallerRuntimeIdentifier.LastIndexOf('-'))))</TargetRuntimeOS> - <TargetArchitecture Condition="'$(TargetArchitecture)' == ''">$(InstallerRuntimeIdentifier.Substring($(InstallerRuntimeIdentifier.LastIndexOf('-'))).TrimStart('-'))</TargetArchitecture> - <InstallerTargetArchitecture Condition="'$(InstallerTargetArchitecture)' == ''">$(TargetArchitecture)</InstallerTargetArchitecture> - </PropertyGroup> - <ItemGroup> - <CrossArchMsiToBuild Include="@(CrossArchSdkMsiInstallerArch)" Exclude="$(TargetArchitecture)" /> - </ItemGroup> - <PropertyGroup> - <_osSupportsWixBasedInstallers Condition="$([MSBuild]::IsOsPlatform(Windows)) and '$(TargetRuntimeOS)' == 'win'">true</_osSupportsWixBasedInstallers> - - <_osArchSupportsWixBasedInstallers>$(_osSupportsWixBasedInstallers)</_osArchSupportsWixBasedInstallers> - <_osArchSupportsWixBasedInstallers Condition="'$(TargetArchitecture)' == 'arm'">false</_osArchSupportsWixBasedInstallers> - </PropertyGroup> - </Target> - - <Target Name="_GetVersionInfo"> - <PropertyGroup> - <IncludePreReleaseLabelInPackageVersion Condition="'$(DotNetFinalVersionKind)' != 'release'">true</IncludePreReleaseLabelInPackageVersion> - <IncludePreReleaseLabelInPackageVersion Condition="'$(SuppressFinalPackageVersion)' == 'true'">true</IncludePreReleaseLabelInPackageVersion> - <IncludePreReleaseLabelInPackageVersion Condition="'$(IsShipping)' != 'true'">true</IncludePreReleaseLabelInPackageVersion> - </PropertyGroup> - </Target> - - <Target Name="_GetProductBrandName" DependsOnTargets="_GetVersionInfo"> - <PropertyGroup - Condition=" - '$(ReleaseBrandSuffix)' == '' and - '$(PreReleaseVersionLabel)' != '' and - '$(PreReleaseVersionIteration)' != ''"> - <!-- Convert 'preview.7' to 'Preview 7'. - 'preview' will come from the pre-release version iteration and the numeric value - will be the PreReleaseVersionIteration. --> - - <ReleaseBrandSuffix>$(PreReleaseVersionLabel.Substring(0,1).ToUpperInvariant())</ReleaseBrandSuffix> - <ReleaseBrandSuffix>$(ReleaseBrandSuffix)$(PreReleaseVersionLabel.Substring(1))</ReleaseBrandSuffix> - <ReleaseBrandSuffix>$(ReleaseBrandSuffix) $(PreReleaseVersionIteration)</ReleaseBrandSuffix> - </PropertyGroup> - - <Error - Text="When building installers a ProductBrandPrefix is required." - Condition="'$(ProductBrandPrefix)' == ''" /> - <Error - Text="When building installers a PackageBrandNameSuffix is required." - Condition="'$(PackageBrandNameSuffix)' == '' and '$(MSBuildProjectExtension)' != '.bundleproj'" /> - <Error - Text="When building a bundle installer, a BundleNameSuffix must be specified." - Condition="'$(BundleNameSuffix)' == '' and '$(MSBuildProjectExtension)' == '.bundleproj'" /> - - <PropertyGroup> - <ProductBrandSuffix>$(VersionPrefix)</ProductBrandSuffix> - <ProductBrandSuffix Condition="'$(ReleaseBrandSuffix)'!=''">$(VersionPrefix) $(ReleaseBrandSuffix)</ProductBrandSuffix> - <ProductBrandName Condition="'$(MSBuildProjectExtension)' == '.bundleproj'">$(ProductBrandPrefix) $(BundleNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> - <ProductBrandName Condition="'$(ProductBrandName)' == ''">$(ProductBrandPrefix) $(PackageBrandNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> - </PropertyGroup> - </Target> - - <PropertyGroup> - <InstallerRuntimeIdentifiers Condition="'$(InstallerRuntimeIdentifiers)' == ''">$(RuntimeIdentifiers)</InstallerRuntimeIdentifiers> - <InstallerRuntimeIdentifier Condition="'$(InstallerRuntimeIdentifier)' == ''">$(RuntimeIdentifier)</InstallerRuntimeIdentifier> - </PropertyGroup> - - <Import Project="$(MSBuildThisFileDirectory)installer.targets" - Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' != ''" /> - <Import Project="$(MSBuildThisFileDirectory)installer.multirid.targets" - Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' == ''" /> - <Import Project="$(MSBuildThisFileDirectory)bundle.targets" - Condition="'$(MSBuildProjectExtension)' == '.bundleproj'" /> + <Import Project="$(MicrosoftDotNetBuildTasksInstallersMSBuildDir)installer.targets" /> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets index fe51d7d393c..a981e33d3dc 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/Directory.Build.targets @@ -8,5 +8,5 @@ <GenerateInstallers>true</GenerateInstallers> </PropertyGroup> - <Import Project="$(MSBuildThisFileDirectory)..\installer.targets" Condition="'$(_InstallerTargetsImported)' != 'true'" /> + <Import Project="$(MSBuildThisFileDirectory)..\installer.singlerid.targets" Condition="'$(_InstallerTargetsImported)' != 'true'" /> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.props b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.props index 14db6908e8a..5fc6934544b 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.props +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.props @@ -3,4 +3,13 @@ <VersionInstallerName>true</VersionInstallerName> <IncludeVersionInMacOSComponentName>true</IncludeVersionInMacOSComponentName> </PropertyGroup> + + <UsingTask TaskName="BuildFPMToolPreReqs" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> + <UsingTask TaskName="CreateLightCommandPackageDrop" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="ExecWithRetries" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateCurrentVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateGuidFromName" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="GenerateJsonObjectString" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)"/> + <UsingTask TaskName="GenerateMsiVersion" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> + <UsingTask TaskName="StabilizeWixFileId" AssemblyFile="$(MicrosoftDotNetBuildTasksInstallersTaskAssembly)" /> </Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.singlerid.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.singlerid.targets new file mode 100644 index 00000000000..28d2ca9574d --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.singlerid.targets @@ -0,0 +1,481 @@ +<Project> + <PropertyGroup> + <_InstallerTargetsImported>true</_InstallerTargetsImported> + </PropertyGroup> + <Target Name="GetInstallerGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo"> + <!-- Filter the installer generation/build flags for the current build machine. --> + <PropertyGroup> + <!-- + Save the project's GenerateInstallers setting. It's possible the current arch of the current OS + doesn't support MSI generation, but we still want to create an MSI across architectures. For + example, we want to make an MSI that installs the arm apphost pack into the x64 SDK location + on an x64 machine. + --> + <GenerateCrossArchMsi Condition="'$(_osSupportsWixBasedInstallers)' == 'true'">true</GenerateCrossArchMsi> + + <GenerateMSI Condition="'$(_osArchSupportsWixBasedInstallers)' == 'true'">true</GenerateMSI> + + <GeneratePkg Condition="$([MSBuild]::IsOSPlatform('osx')) and '$(TargetRuntimeOS)' == 'osx'">true</GeneratePkg> + </PropertyGroup> + + <!-- + Apply the global Build*Package properties. These use distro-specific logic to determine if the + current distro should build RPM packages or Debian packages. + + This logic is external because the legacy infra needs the values. + --> + <PropertyGroup> + <GenerateDeb>$(GenerateInstallers)</GenerateDeb> + <GenerateRpm>$(GenerateInstallers)</GenerateRpm> + <GenerateDeb Condition="'$(GenerateDeb)' == 'true' and '$(BuildDebPackage)' != 'true'">false</GenerateDeb> + <GenerateRpm Condition="'$(GenerateRpm)' == 'true' and '$(BuildRpmPackage)' != 'true'">false</GenerateRpm> + </PropertyGroup> + </Target> + + <!-- + Shared targets to build installers and distro packages. + --> + <Import Project="$(MSBuildThisFileDirectory)wix/wix.targets" /> + + <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipInstallerBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> + <ItemGroup> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateDeb" + Properties="GenerateDeb=true" + Condition="'$(GenerateDeb)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateRpm" + Properties="GenerateRpm=true" + Condition="'$(GenerateRpm)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateMsi" + Properties="GenerateMSI=true" + Condition="'$(GenerateMSI)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateCrossArchMsi" + Properties="GenerateCrossArchMsi=true" + Condition="'$(GenerateCrossArchMsi)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GeneratePkg" + Properties="GeneratePkg=true" + Condition="'$(GeneratePkg)' == 'true'" /> + <_InstallerBuildProject + Include="$(MSBuildProjectFile)" + Targets="GenerateVSInsertionNupkg" + Properties="GenerateMSI=$(GenerateMSI);GenerateCrossArchMsi=$(GenerateCrossArchMsi)" + Condition="'$(GenerateVSInsertionPackages)' == 'true'" /> + </ItemGroup> + <MSBuild Projects="@(_InstallerBuildProject)" + Targets="%(_InstallerBuildProject.Targets)" + BuildInParallel="$(BuildInParallel)" /> + </Target> + + <Target Name="GenerateDeb" DependsOnTargets="FindDebuild;CreateDeb" /> + <Target Name="GenerateRpm" DependsOnTargets="FindFPM;CreateRpm" /> + <Target Name="GenerateMsi" DependsOnTargets="CreateWixInstaller" /> + <Target Name="GenerateCrossArchMsi" DependsOnTargets="CreateCrossArchWixInstaller" /> + <Target Name="GeneratePkg" DependsOnTargets="CreatePkg" /> + + <!-- + Set up properties for installer generation. Project-type-specific properties are set up in + targets that use BeforeTargets="_GetInstallerProperties". + --> + <Target Name="_GetInstallerProperties" + DependsOnTargets="_GetTargetOSArchInfo; + _GetProductBrandName"> + <Error + Text="InstallerName '$(InstallerName)' is empty or starts with a '-': expected a value like 'dotnet-runtime'." + Condition="'$(InstallerName)' == '' or $(InstallerName.StartsWith('-'))" /> + + <PropertyGroup> + <VersionedInstallerName Condition="'$(VersionInstallerName)' == 'true'">$(InstallerName)-$(MajorVersion).$(MinorVersion)</VersionedInstallerName> + <VersionedInstallerName Condition="'$(VersionInstallerName)' != 'true'">$(InstallerName)</VersionedInstallerName> + <VersionedInstallerName>$(VersionedInstallerName.ToLowerInvariant())</VersionedInstallerName> + <InstallerPackageRelease>1</InstallerPackageRelease> + <InstallerPackageVersion>$(VersionPrefix)</InstallerPackageVersion> + </PropertyGroup> + + <!-- Distinguish the cross-arch installer filename. --> + <PropertyGroup Condition="'$(CrossArchContentsArch)' != ''"> + <CrossArchContentsBuildPart>_$(CrossArchContentsArch)</CrossArchContentsBuildPart> + </PropertyGroup> + + <PropertyGroup> + <InstallerExtension Condition="'$(GenerateMsi)' == 'true' or '$(GenerateCrossArchMsi)' == 'true'">.msi</InstallerExtension> + <InstallerExtension Condition="'$(GeneratePkg)' == 'true'">.pkg</InstallerExtension> + <InstallerExtension Condition="'$(GenerateDeb)' == 'true'">.deb</InstallerExtension> + <InstallerExtension Condition="'$(GenerateRpm)' == 'true'">.rpm</InstallerExtension> + <CombinedInstallerExtension Condition="'$(TargetRuntimeOS)' == 'win'">.exe</CombinedInstallerExtension> + <CombinedInstallerExtension Condition="'$(TargetRuntimeOS)' != 'win'">$(InstallerExtension)</CombinedInstallerExtension> + </PropertyGroup> + + <PropertyGroup Condition="'$(GenerateDeb)' == 'true'"> + <InstallerPackageVersion Condition="'$(IncludePreReleaseLabelInPackageVersion)' == 'true'">$(VersionPrefix)~$(VersionSuffix)</InstallerPackageVersion> + </PropertyGroup> + + <PropertyGroup Condition="'$(GenerateRpm)' == 'true'"> + <InstallerPackageRelease Condition="'$(IncludePreReleaseLabelInPackageVersion)' == 'true'">0.1.$(VersionSuffix)</InstallerPackageRelease> + <InstallerPackageRelease>$([System.String]::Copy('$(InstallerPackageRelease)').Replace('-', '_'))</InstallerPackageRelease> + </PropertyGroup> + + <PropertyGroup> + <_InstallerIntermediatesDir>$(IntermediateOutputPath)$(InstallerName)/$(InstallerPackageVersion)/</_InstallerIntermediatesDir> + + <InstallerBuildPart>$(Version)-$(TargetRuntimeOS)-$(InstallerTargetArchitecture)</InstallerBuildPart> + </PropertyGroup> + <PropertyGroup Condition="'$(GenerateDeb)' == 'true' or '$(GenerateRpm)' == 'true'"> + <InstallerBuildPart>$(ProductVersion)-$(InstallerTargetArchitecture)</InstallerBuildPart> + <InstallerBuildPart Condition="'$(PackageTargetOS)' != ''">$(ProductVersion)-$(PackageTargetOS)-$(InstallerTargetArchitecture)</InstallerBuildPart> + </PropertyGroup> + <PropertyGroup> + <!-- Location to place the installer, in artifacts. --> + <InstallerFileNameWithoutExtension>$(InstallerName)-$(InstallerBuildPart)$(CrossArchContentsBuildPart)</InstallerFileNameWithoutExtension> + <_InstallerFile Condition="'$(_InstallerFile)' == ''">$(PackageOutputPath)$(InstallerFileNameWithoutExtension)$(InstallerExtension)</_InstallerFile> + <ExeBundleInstallerFile>$(PackageOutputPath)$(InstallerFileNameWithoutExtension).exe</ExeBundleInstallerFile> + <ExeBundleInstallerEngineFile>$(PackageOutputPath)$(InstallerFileNameWithoutExtension)-engine.exe</ExeBundleInstallerEngineFile> + </PropertyGroup> + </Target> + + <!-- + Check if the deb package build tool prereq is available. + --> + <Target Name="FindDebuild"> + <!-- run Debuild --> + <Exec + Command="/usr/bin/env debuild -h > /dev/null 2>&1" + ContinueOnError="true" + IgnoreExitCode="true" + IgnoreStandardErrorWarningFormat="true"> + <Output TaskParameter="ExitCode" PropertyName="_DebuildSearchExitCode" /> + </Exec> + + <!-- Check if it successfully showed us a help message. --> + <PropertyGroup> + <_DebuildPresent>false</_DebuildPresent> + <_DebuildPresent Condition=" '$(_DebuildSearchExitCode)' == '0' ">true</_DebuildPresent> + </PropertyGroup> + + <Error Condition=" '$(_DebuildPresent)' != 'true' " + Text="Debuild Not found, Debian packages will not be built." /> + </Target> + + <!-- + Check if the RPM package build tool prereq is available. + --> + <Target Name="FindFPM"> + <!-- run FPM --> + <Exec + Command="/usr/bin/env fpm -h > /dev/null 2>&1" + ContinueOnError="true" + IgnoreExitCode="true" + IgnoreStandardErrorWarningFormat="true"> + <Output TaskParameter="ExitCode" PropertyName="_FPMSearchExitCode" /> + </Exec> + + <!-- Check if it successfully showed us a help message. --> + <PropertyGroup> + <_FPMPresent>false</_FPMPresent> + <_FPMPresent Condition=" '$(_FPMSearchExitCode)' == '0' ">true</_FPMPresent> + </PropertyGroup> + + <Error Condition=" '$(_FPMPresent)' != 'true' " + Text="FPM tool Not found, RPM packages will not be built." /> + </Target> + + <!-- + Create Debian package. + --> + <Target Name="CreateDeb" + DependsOnTargets=" + _GetInstallerProperties; + _CreateInstallerLayout; + GetDebInstallerJsonProperties" + Condition="'$(_DebuildPresent)' == 'true'" + Returns="$(_InstallerFile)"> + <PropertyGroup> + <_ConfigJsonFile>$(_LayoutDirectory)debian_config.json</_ConfigJsonFile> + <_DebIntermediatesDir>$(IntermediateOutputPath)out-deb</_DebIntermediatesDir> + + <_DebToolArgs>-i $(_LayoutDirectory)</_DebToolArgs> + <_DebToolArgs>$(_DebToolArgs) -o $(_DebIntermediatesDir)</_DebToolArgs> + <_DebToolArgs>$(_DebToolArgs) -n $(VersionedInstallerName)</_DebToolArgs> + <_DebToolArgs>$(_DebToolArgs) -v $(InstallerPackageVersion)</_DebToolArgs> + </PropertyGroup> + + <!-- Write the configuration JSON. --> + <GenerateJsonObjectString + Properties="@(_CommonLinuxPackageProperty);@(_DebJsonProperty)" + TargetFile="$(_ConfigJsonFile)" /> + + <!-- Run deb tool in the directory of the consumer project. --> + <Exec + Command="/usr/bin/env bash $(MSBuildThisFileDirectory)deb-package-tool/package_tool.sh $(_DebToolArgs)" + IgnoreStandardErrorWarningFormat="true" /> + + <!-- Copy package to output. --> + <ItemGroup> + <_GeneratedDebFiles Include="$(_DebIntermediatesDir)/*.deb" /> + </ItemGroup> + + <Error Text="@(_GeneratedDebFiles->Count()) .deb files generated." Condition="'@(_GeneratedDebFiles->Count())' != 1" /> + + <Copy SourceFiles="@(_GeneratedDebFiles)" + DestinationFiles="$(_InstallerFile)" + OverwriteReadOnlyFiles="True" + SkipUnchangedFiles="False" + UseHardlinksIfPossible="False" /> + + <Message Text="$(MSBuildProjectName) -> $(_InstallerFile)" Importance="high" /> + </Target> + + <Target Name="GetDebInstallerJsonProperties" + DependsOnTargets="_GetCommonJsonProperties"> + <ItemGroup> + <_DebDependenciesJsonEntry Include="@(LinuxPackageDependency->'"%(Identity)" : { "package_version" : "%(Version)"}')" /> + </ItemGroup> + <ItemGroup> + <_DebJsonProperty Include="debian_dependencies" Object="{@(_DebDependenciesJsonEntry, ', ')}" /> + <_DebJsonProperty Include="@(DebJsonProperty)" /> + </ItemGroup> + </Target> + + <!-- + Create RPM package. + --> + <Target Name="CreateRpm" + DependsOnTargets=" + _GetInstallerProperties; + _CreateInstallerLayout; + GetRpmInstallerJsonProperties" + Condition="'$(_FPMPresent)' == 'true'" + Returns="$(_InstallerFile)"> + <PropertyGroup> + <_ConfigJsonFile>$(_LayoutDirectory)rpm_config.json</_ConfigJsonFile> + <_RpmIntermediatesDir>$(_InstallerIntermediatesDir)out-rpm</_RpmIntermediatesDir> + + <!-- Copyright, Changelog --> + <_RpmTemplatesLayoutDir>$(_LayoutDirectory)templates/</_RpmTemplatesLayoutDir> + </PropertyGroup> + + <ItemGroup> + <_RpmTemplateFile Include="$(MSBuildThisFileDirectory)rpm_templates/**/*" /> + </ItemGroup> + + <Copy + SourceFiles="@(_RpmTemplateFile)" + DestinationFiles="@(_RpmTemplateFile->'$(_RpmTemplatesLayoutDir)%(RecursiveDir)%(Filename)%(Extension)')" /> + + <GenerateJsonObjectString + Properties="@(_CommonLinuxPackageProperty);@(_RpmJsonProperty)" + TargetFile="$(_ConfigJsonFile)" /> + + <MakeDir Directories="$(_RpmIntermediatesDir)" /> + + <!-- Call the task to build the pre-reqs (parameters, copyright, changelog) for calling the FPM tool --> + <BuildFPMToolPreReqs + InputDir="$(_LayoutDirectory)" + OutputDir="$(_RpmIntermediatesDir)" + PackageVersion="$(InstallerPackageVersion)" + ConfigJsonFile="$(_ConfigJsonFile)"> + <Output TaskParameter="FPMParameters" PropertyName="FPMCmdParameters" /> + </BuildFPMToolPreReqs> + + <Exec Command="fpm $(FPMCmdParameters)" WorkingDirectory="$(_RpmIntermediatesDir)" /> + + <!-- Copy package to output --> + <ItemGroup> + <GeneratedRpmFiles Include="$(_RpmIntermediatesDir)/*.rpm" /> + </ItemGroup> + + <Error Text="@(GeneratedRpmFiles->Count()) .rpm files generated." Condition="'@(GeneratedRpmFiles->Count())' != 1" /> + + <Copy SourceFiles="@(GeneratedRpmFiles)" + DestinationFiles="$(_InstallerFile)" + OverwriteReadOnlyFiles="True" + SkipUnchangedFiles="False" + UseHardlinksIfPossible="False" /> + + <Message Text="$(MSBuildProjectName) -> $(_InstallerFile)" Importance="high" /> + </Target> + + <Target Name="GetRpmInstallerJsonProperties" + DependsOnTargets="_GetCommonJsonProperties"> + <ItemGroup> + <_FpmDependenciesJsonEntry Include="@(LinuxPackageDependency->'{"package_name" : "%(Identity)", "package_version" : "%(Version)"}')" /> + </ItemGroup> + <ItemGroup> + <_RpmJsonProperty Include="vendor" String=".NET Foundation" /> + <_RpmJsonProperty Include="install_doc" String="/usr/share/doc/$(VersionedInstallerName)/" /> + <_RpmJsonProperty Include="rpm_dependencies" Object="[@(_FpmDependenciesJsonEntry,', ')]" /> + <_RpmJsonProperty Include="@(RpmJsonProperty)" /> + </ItemGroup> + </Target> + + <!-- + Create MSI installer, using WiX tools. + --> + <Target Name="CreateWixInstaller" + DependsOnTargets=" + _GetInstallerProperties; + RunLightLinker" + Returns="$(_OutInstallerFile)"> + <Error + Condition="'$(GenerateExeBundle)' == 'true' and '$(GenerateMSI)' == 'true'" + Text="GenerateExeBundle and GenerateMSI are both set, but only one can be created at a time." /> + + <Message Text="$(MSBuildProjectName) -> $(_OutInstallerFile)" Importance="high" /> + </Target> + + <!-- + Create MSI installers that install the current architecture's assets into the proper location + for a different architecture's SDK to find. + --> + <Target Name="CreateCrossArchWixInstaller" + DependsOnTargets="_GetTargetOSArchInfo" + Returns="@(_CrossArchMsi)"> + <MSBuild + Condition="'@(CrossArchMsiToBuild)' != ''" + Projects="$(MSBuildProjectFullPath)" + Targets="CreateWixInstaller" + Properties=" + InstallerTargetArchitecture=%(CrossArchMsiToBuild.Identity); + CrossArchContentsArch=$(TargetArchitecture); + GenerateMSI=true"> + <Output TaskParameter="TargetOutputs" ItemName="_CrossArchMsi" /> + </MSBuild> + </Target> + + <!-- + Create macOS pkg installer. + --> + <Target Name="CreatePkg" + DependsOnTargets=" + _GetInstallerProperties; + _CreateInstallerLayout" + Returns="@(_CreatedPkg)"> + + <!-- Copy files to layout. --> + <PropertyGroup> + <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> + </PropertyGroup> + + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishToDisk" + Properties="OutputPath=$(_OutputPathRoot)" + RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> + <PropertyGroup> + <_MacOSVersionComponent Condition="'$(IncludeVersionInMacOSComponentName)' == 'true'">.$(ProductVersion)</_MacOSVersionComponent> + <_MacOSComponentName Condition="'$(_MacOSComponentName)' == ''">com.microsoft.dotnet.$(MacOSComponentNamePackType)$(_MacOSVersionComponent).component.osx.x64</_MacOSComponentName> + <_MacOSSharedInstallDir>/usr/local/share/dotnet</_MacOSSharedInstallDir> + + <_pkgArgs></_pkgArgs> + <_pkgArgs>$(_pkgArgs) --root $(_OutputPathRoot)</_pkgArgs> + <_pkgArgs>$(_pkgArgs) --identifier $(_MacOSComponentName)</_pkgArgs> + <_pkgArgs>$(_pkgArgs) --version $(ProductVersion)</_pkgArgs> + <_pkgArgs>$(_pkgArgs) --install-location $(_MacOSSharedInstallDir)</_pkgArgs> + <_pkgArgs Condition="'$(MacOSScriptsDirectory)' != ''">$(_pkgArgs) --scripts $(MacOSScriptsDirectory)</_pkgArgs> + <_pkgArgs>$(_pkgArgs) $(_InstallerFile)</_pkgArgs> + </PropertyGroup> + + <Exec Command="pkgbuild $(_pkgArgs)" /> + + <Message Text="$(MSBuildProjectName) -> $(_InstallerFile)" Importance="high" /> + <ItemGroup> + <_CreatedPkg Include="$(_InstallerFile)" Description="$(MacOSPackageDescription)" Title="$(ProductBrandName) ($(TargetArchitecture))" /> + </ItemGroup> + </Target> + + <!-- + Create installer layout. Used for RPM and Deb package creation. + --> + <Target Name="_CreateInstallerLayout"> + <PropertyGroup> + <_LayoutDirectory>$(IntermediateOutputPath)installer/layoutDirectory/</_LayoutDirectory> + <_LayoutPackageRoot>$(_LayoutDirectory)package_root</_LayoutPackageRoot> + <_LayoutAbsolute>$(_LayoutDirectory)$</_LayoutAbsolute> + <_LayoutSamples>$(_LayoutDirectory)samples</_LayoutSamples> + <_LayoutDocs>$(_LayoutDirectory)docs</_LayoutDocs> + </PropertyGroup> + + <RemoveDir Condition="Exists('$(_InstallerIntermediatesDir)')" Directories="$(_InstallerIntermediatesDir)" /> + <MakeDir Directories="$(_InstallerIntermediatesDir)" /> + + <!-- Create empty layout. --> + <RemoveDir Condition="Exists('$(_LayoutDirectory)')" Directories="$(_LayoutDirectory)" /> + <MakeDir Directories="$(_LayoutDirectory)" /> + <MakeDir Directories="$(_LayoutAbsolute)" /> + <MakeDir Directories="$(_LayoutPackageRoot)" /> + <MakeDir Directories="$(_LayoutSamples)" /> + <MakeDir Directories="$(_LayoutDocs)" /> + + <MSBuild Projects="$(MSBuildProjectFullPath)" + Targets="PublishToDisk" + Properties="OutputPath=$(_LayoutPackageRoot)" + RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> + + <Copy + SourceFiles="@(Manpage)" + DestinationFiles="@(Manpage->'$(_LayoutDocs)/%(RecursiveDir)%(Filename)%(Extension)')" /> + </Target> + + <!-- + Get common JSON properties. Used in the configuration JSON for both RPM and Debian packages. + --> + <Target Name="_GetCommonJsonProperties"> + <PropertyGroup> + <FullLicenseText>$([System.IO.File]::ReadAllText('$(LicenseFile)').Replace('%0A', '\n').Replace('"', '\"'))</FullLicenseText> + </PropertyGroup> + + <ItemGroup> + <_LinuxPackageReleaseProperty Include="package_version" String="1.0.0.0" /> + <_LinuxPackageReleaseProperty Include="package_revision" String="$(InstallerPackageRelease)" /> + <_LinuxPackageReleaseProperty Include="urgency" String="low" /> + <_LinuxPackageReleaseProperty Include="changelog_message" String="https://github.com/dotnet/core/tree/master/release-notes" /> + + <_LinuxPackageControlProperty Include="priority" String="standard" /> + <_LinuxPackageControlProperty Include="section" String="libs" /> + <_LinuxPackageControlProperty Include="architecture" String="amd64" /> + + <_LinuxPackageLicenseProperty Include="type" String="MIT and ASL 2.0 and BSD" /> + <_LinuxPackageLicenseProperty Include="full_text" String="$(FullLicenseText)" /> + </ItemGroup> + + <GenerateJsonObjectString Properties="@(_LinuxPackageReleaseProperty)"> + <Output TaskParameter="Json" PropertyName="_JsonReleaseObject" /> + </GenerateJsonObjectString> + <GenerateJsonObjectString Properties="@(_LinuxPackageControlProperty)"> + <Output TaskParameter="Json" PropertyName="_JsonControlObject" /> + </GenerateJsonObjectString> + <GenerateJsonObjectString Properties="@(_LinuxPackageLicenseProperty)"> + <Output TaskParameter="Json" PropertyName="_JsonLicenseObject" /> + </GenerateJsonObjectString> + + <PropertyGroup> + <_ShortDescription>$(MSBuildProjectName) $(InstallerPackageVersion)</_ShortDescription> + <_ShortDescription Condition="'$(UseBrandingNameInLinuxPackageDescription)' == 'true'">$(ProductBrandName)</_ShortDescription> + </PropertyGroup> + + <ItemGroup> + <_CommonLinuxPackageProperty Include="package_name" String="$(VersionedInstallerName)" /> + <_CommonLinuxPackageProperty Include="short_description" String="$(_ShortDescription)" /> + <_CommonLinuxPackageProperty Include="maintainer_name" String=".NET Team" /> + <_CommonLinuxPackageProperty Include="maintainer_email" String="dotnetpackages@dotnetfoundation.org" /> + <_CommonLinuxPackageProperty Include="install_root" String="/usr/share/dotnet" /> + <_CommonLinuxPackageProperty Include="long_description" String=".NET is a development platform that you can use to build command-line applications, microservices and modern websites. 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 (https://github.com/dotnet/core). We happily accept issues and PRs." /> + <_CommonLinuxPackageProperty Include="homepage" String="https://github.com/dotnet/core" /> + <_CommonLinuxPackageProperty Include="copyright" String="2017 Microsoft" /> + <_CommonLinuxPackageProperty Include="release" Object="$(_JsonReleaseObject)" /> + <_CommonLinuxPackageProperty Include="control" Object="$(_JsonControlObject)" /> + <_CommonLinuxPackageProperty Include="license" Object="$(_JsonLicenseObject)" /> + </ItemGroup> + </Target> + + <PropertyGroup> + <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps;GenerateInstallers</BuildDependsOn> + </PropertyGroup> +</Project> diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets index 28d2ca9574d..9f0427cf6b0 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets +++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.targets @@ -1,481 +1,155 @@ <Project> - <PropertyGroup> - <_InstallerTargetsImported>true</_InstallerTargetsImported> - </PropertyGroup> - <Target Name="GetInstallerGenerationFlags" DependsOnTargets="_GetTargetOSArchInfo"> - <!-- Filter the installer generation/build flags for the current build machine. --> - <PropertyGroup> - <!-- - Save the project's GenerateInstallers setting. It's possible the current arch of the current OS - doesn't support MSI generation, but we still want to create an MSI across architectures. For - example, we want to make an MSI that installs the arm apphost pack into the x64 SDK location - on an x64 machine. - --> - <GenerateCrossArchMsi Condition="'$(_osSupportsWixBasedInstallers)' == 'true'">true</GenerateCrossArchMsi> - - <GenerateMSI Condition="'$(_osArchSupportsWixBasedInstallers)' == 'true'">true</GenerateMSI> - - <GeneratePkg Condition="$([MSBuild]::IsOSPlatform('osx')) and '$(TargetRuntimeOS)' == 'osx'">true</GeneratePkg> - </PropertyGroup> - - <!-- - Apply the global Build*Package properties. These use distro-specific logic to determine if the - current distro should build RPM packages or Debian packages. - - This logic is external because the legacy infra needs the values. - --> - <PropertyGroup> - <GenerateDeb>$(GenerateInstallers)</GenerateDeb> - <GenerateRpm>$(GenerateInstallers)</GenerateRpm> - <GenerateDeb Condition="'$(GenerateDeb)' == 'true' and '$(BuildDebPackage)' != 'true'">false</GenerateDeb> - <GenerateRpm Condition="'$(GenerateRpm)' == 'true' and '$(BuildRpmPackage)' != 'true'">false</GenerateRpm> - </PropertyGroup> - </Target> - - <!-- - Shared targets to build installers and distro packages. - --> - <Import Project="$(MSBuildThisFileDirectory)wix/wix.targets" /> - - <Target Name="GenerateInstallers" DependsOnTargets="GetInstallerGenerationFlags" Condition="'$(SkipInstallerBuild)' != 'true' and '$(GenerateInstallers)' == 'true'"> + <Target Name="_GetCurrentProjectServicingConfiguration"> <ItemGroup> - <_InstallerBuildProject - Include="$(MSBuildProjectFile)" - Targets="GenerateDeb" - Properties="GenerateDeb=true" - Condition="'$(GenerateDeb)' == 'true'" /> - <_InstallerBuildProject - Include="$(MSBuildProjectFile)" - Targets="GenerateRpm" - Properties="GenerateRpm=true" - Condition="'$(GenerateRpm)' == 'true'" /> - <_InstallerBuildProject - Include="$(MSBuildProjectFile)" - Targets="GenerateMsi" - Properties="GenerateMSI=true" - Condition="'$(GenerateMSI)' == 'true'" /> - <_InstallerBuildProject - Include="$(MSBuildProjectFile)" - Targets="GenerateCrossArchMsi" - Properties="GenerateCrossArchMsi=true" - Condition="'$(GenerateCrossArchMsi)' == 'true'" /> - <_InstallerBuildProject - Include="$(MSBuildProjectFile)" - Targets="GeneratePkg" - Properties="GeneratePkg=true" - Condition="'$(GeneratePkg)' == 'true'" /> - <_InstallerBuildProject - Include="$(MSBuildProjectFile)" - Targets="GenerateVSInsertionNupkg" - Properties="GenerateMSI=$(GenerateMSI);GenerateCrossArchMsi=$(GenerateCrossArchMsi)" - Condition="'$(GenerateVSInsertionPackages)' == 'true'" /> + <CurrentProjectServicingConfiguration + Include="@(ProjectServicingConfiguration)" + Condition="'%(Identity)' == '$(MSBuildProjectName)'" /> </ItemGroup> - <MSBuild Projects="@(_InstallerBuildProject)" - Targets="%(_InstallerBuildProject.Targets)" - BuildInParallel="$(BuildInParallel)" /> </Target> - <Target Name="GenerateDeb" DependsOnTargets="FindDebuild;CreateDeb" /> - <Target Name="GenerateRpm" DependsOnTargets="FindFPM;CreateRpm" /> - <Target Name="GenerateMsi" DependsOnTargets="CreateWixInstaller" /> - <Target Name="GenerateCrossArchMsi" DependsOnTargets="CreateCrossArchWixInstaller" /> - <Target Name="GeneratePkg" DependsOnTargets="CreatePkg" /> - <!-- - Set up properties for installer generation. Project-type-specific properties are set up in - targets that use BeforeTargets="_GetInstallerProperties". + The Microsoft build's per-package servicing policy conflicts with the source-build restrictions. + Targeting packs, for example, are only built/published when there's a known change to release. + This is in contrast to runtime packs and the shared framework, which are always built and + published. This means it's common in the Microsoft build for downstream repos to depend on two + builds' outputs: the current build's runtime assets, and some old build's targeting pack. + + The Microsoft build can simply download the old targeting pack from NuGet.org. Source-build + can't do this because the bits on NuGet.org are not built locally. Instead, source-build assumes + it's possible to use current sources to build a package with the old version. This target + applies the old build's patch version to make that happen. + + This solution has pitfalls. More info at https://github.com/dotnet/core-setup/issues/8735. The + target supports SkipSetLastReleasedVersionForSourceBuild (unused as of writing) to allow + disabling this workaround if a better way forward is implemented. --> - <Target Name="_GetInstallerProperties" - DependsOnTargets="_GetTargetOSArchInfo; - _GetProductBrandName"> - <Error - Text="InstallerName '$(InstallerName)' is empty or starts with a '-': expected a value like 'dotnet-runtime'." - Condition="'$(InstallerName)' == '' or $(InstallerName.StartsWith('-'))" /> - - <PropertyGroup> - <VersionedInstallerName Condition="'$(VersionInstallerName)' == 'true'">$(InstallerName)-$(MajorVersion).$(MinorVersion)</VersionedInstallerName> - <VersionedInstallerName Condition="'$(VersionInstallerName)' != 'true'">$(InstallerName)</VersionedInstallerName> - <VersionedInstallerName>$(VersionedInstallerName.ToLowerInvariant())</VersionedInstallerName> - <InstallerPackageRelease>1</InstallerPackageRelease> - <InstallerPackageVersion>$(VersionPrefix)</InstallerPackageVersion> - </PropertyGroup> - - <!-- Distinguish the cross-arch installer filename. --> - <PropertyGroup Condition="'$(CrossArchContentsArch)' != ''"> - <CrossArchContentsBuildPart>_$(CrossArchContentsArch)</CrossArchContentsBuildPart> - </PropertyGroup> - - <PropertyGroup> - <InstallerExtension Condition="'$(GenerateMsi)' == 'true' or '$(GenerateCrossArchMsi)' == 'true'">.msi</InstallerExtension> - <InstallerExtension Condition="'$(GeneratePkg)' == 'true'">.pkg</InstallerExtension> - <InstallerExtension Condition="'$(GenerateDeb)' == 'true'">.deb</InstallerExtension> - <InstallerExtension Condition="'$(GenerateRpm)' == 'true'">.rpm</InstallerExtension> - <CombinedInstallerExtension Condition="'$(TargetRuntimeOS)' == 'win'">.exe</CombinedInstallerExtension> - <CombinedInstallerExtension Condition="'$(TargetRuntimeOS)' != 'win'">$(InstallerExtension)</CombinedInstallerExtension> - </PropertyGroup> - - <PropertyGroup Condition="'$(GenerateDeb)' == 'true'"> - <InstallerPackageVersion Condition="'$(IncludePreReleaseLabelInPackageVersion)' == 'true'">$(VersionPrefix)~$(VersionSuffix)</InstallerPackageVersion> - </PropertyGroup> - - <PropertyGroup Condition="'$(GenerateRpm)' == 'true'"> - <InstallerPackageRelease Condition="'$(IncludePreReleaseLabelInPackageVersion)' == 'true'">0.1.$(VersionSuffix)</InstallerPackageRelease> - <InstallerPackageRelease>$([System.String]::Copy('$(InstallerPackageRelease)').Replace('-', '_'))</InstallerPackageRelease> - </PropertyGroup> - + <Target Name="SetLastReleasedVersionForSourceBuild" + Condition=" + '$(DotNetBuildFromSource)' == 'true' and + '$(SkipSetLastReleasedVersionForSourceBuild)' != 'true'" + BeforeTargets="GetProductVersions" + DependsOnTargets="_GetCurrentProjectServicingConfiguration"> <PropertyGroup> - <_InstallerIntermediatesDir>$(IntermediateOutputPath)$(InstallerName)/$(InstallerPackageVersion)/</_InstallerIntermediatesDir> - - <InstallerBuildPart>$(Version)-$(TargetRuntimeOS)-$(InstallerTargetArchitecture)</InstallerBuildPart> - </PropertyGroup> - <PropertyGroup Condition="'$(GenerateDeb)' == 'true' or '$(GenerateRpm)' == 'true'"> - <InstallerBuildPart>$(ProductVersion)-$(InstallerTargetArchitecture)</InstallerBuildPart> - <InstallerBuildPart Condition="'$(PackageTargetOS)' != ''">$(ProductVersion)-$(PackageTargetOS)-$(InstallerTargetArchitecture)</InstallerBuildPart> - </PropertyGroup> - <PropertyGroup> - <!-- Location to place the installer, in artifacts. --> - <InstallerFileNameWithoutExtension>$(InstallerName)-$(InstallerBuildPart)$(CrossArchContentsBuildPart)</InstallerFileNameWithoutExtension> - <_InstallerFile Condition="'$(_InstallerFile)' == ''">$(PackageOutputPath)$(InstallerFileNameWithoutExtension)$(InstallerExtension)</_InstallerFile> - <ExeBundleInstallerFile>$(PackageOutputPath)$(InstallerFileNameWithoutExtension).exe</ExeBundleInstallerFile> - <ExeBundleInstallerEngineFile>$(PackageOutputPath)$(InstallerFileNameWithoutExtension)-engine.exe</ExeBundleInstallerEngineFile> + <MostRecentProducedServicingPatchVersion>%(CurrentProjectServicingConfiguration.PatchVersion)</MostRecentProducedServicingPatchVersion> + <PatchVersion Condition="'$(MostRecentProducedServicingPatchVersion)' != ''">$(MostRecentProducedServicingPatchVersion)</PatchVersion> </PropertyGroup> </Target> - - <!-- - Check if the deb package build tool prereq is available. - --> - <Target Name="FindDebuild"> - <!-- run Debuild --> - <Exec - Command="/usr/bin/env debuild -h > /dev/null 2>&1" - ContinueOnError="true" - IgnoreExitCode="true" - IgnoreStandardErrorWarningFormat="true"> - <Output TaskParameter="ExitCode" PropertyName="_DebuildSearchExitCode" /> - </Exec> - - <!-- Check if it successfully showed us a help message. --> - <PropertyGroup> - <_DebuildPresent>false</_DebuildPresent> - <_DebuildPresent Condition=" '$(_DebuildSearchExitCode)' == '0' ">true</_DebuildPresent> - </PropertyGroup> - - <Error Condition=" '$(_DebuildPresent)' != 'true' " - Text="Debuild Not found, Debian packages will not be built." /> - </Target> - - <!-- - Check if the RPM package build tool prereq is available. - --> - <Target Name="FindFPM"> - <!-- run FPM --> - <Exec - Command="/usr/bin/env fpm -h > /dev/null 2>&1" - ContinueOnError="true" - IgnoreExitCode="true" - IgnoreStandardErrorWarningFormat="true"> - <Output TaskParameter="ExitCode" PropertyName="_FPMSearchExitCode" /> - </Exec> - <!-- Check if it successfully showed us a help message. --> - <PropertyGroup> - <_FPMPresent>false</_FPMPresent> - <_FPMPresent Condition=" '$(_FPMSearchExitCode)' == '0' ">true</_FPMPresent> - </PropertyGroup> - - <Error Condition=" '$(_FPMPresent)' != 'true' " - Text="FPM tool Not found, RPM packages will not be built." /> - </Target> - - <!-- - Create Debian package. - --> - <Target Name="CreateDeb" + <Target Name="_GetSkipInstallerBuildProps" DependsOnTargets=" - _GetInstallerProperties; - _CreateInstallerLayout; - GetDebInstallerJsonProperties" - Condition="'$(_DebuildPresent)' == 'true'" - Returns="$(_InstallerFile)"> - <PropertyGroup> - <_ConfigJsonFile>$(_LayoutDirectory)debian_config.json</_ConfigJsonFile> - <_DebIntermediatesDir>$(IntermediateOutputPath)out-deb</_DebIntermediatesDir> - - <_DebToolArgs>-i $(_LayoutDirectory)</_DebToolArgs> - <_DebToolArgs>$(_DebToolArgs) -o $(_DebIntermediatesDir)</_DebToolArgs> - <_DebToolArgs>$(_DebToolArgs) -n $(VersionedInstallerName)</_DebToolArgs> - <_DebToolArgs>$(_DebToolArgs) -v $(InstallerPackageVersion)</_DebToolArgs> + _GetCurrentProjectServicingConfiguration; + SetLastReleasedVersionForSourceBuild"> + <!-- + Skip the build if there is an applicable servicing configuration, and the servicing + configuration indicates this project shouldn't build for this patch version. + --> + <PropertyGroup Condition="'@(CurrentProjectServicingConfiguration)' != ''"> + <SkipInstallerBuild Condition="'%(CurrentProjectServicingConfiguration.PatchVersion)' != '$(PatchVersion)'">true</SkipInstallerBuild> </PropertyGroup> - <!-- Write the configuration JSON. --> - <GenerateJsonObjectString - Properties="@(_CommonLinuxPackageProperty);@(_DebJsonProperty)" - TargetFile="$(_ConfigJsonFile)" /> - - <!-- Run deb tool in the directory of the consumer project. --> - <Exec - Command="/usr/bin/env bash $(MSBuildThisFileDirectory)deb-package-tool/package_tool.sh $(_DebToolArgs)" - IgnoreStandardErrorWarningFormat="true" /> - - <!-- Copy package to output. --> - <ItemGroup> - <_GeneratedDebFiles Include="$(_DebIntermediatesDir)/*.deb" /> - </ItemGroup> - - <Error Text="@(_GeneratedDebFiles->Count()) .deb files generated." Condition="'@(_GeneratedDebFiles->Count())' != 1" /> - - <Copy SourceFiles="@(_GeneratedDebFiles)" - DestinationFiles="$(_InstallerFile)" - OverwriteReadOnlyFiles="True" - SkipUnchangedFiles="False" - UseHardlinksIfPossible="False" /> - - <Message Text="$(MSBuildProjectName) -> $(_InstallerFile)" Importance="high" /> - </Target> - - <Target Name="GetDebInstallerJsonProperties" - DependsOnTargets="_GetCommonJsonProperties"> - <ItemGroup> - <_DebDependenciesJsonEntry Include="@(LinuxPackageDependency->'"%(Identity)" : { "package_version" : "%(Version)"}')" /> - </ItemGroup> <ItemGroup> - <_DebJsonProperty Include="debian_dependencies" Object="{@(_DebDependenciesJsonEntry, ', ')}" /> - <_DebJsonProperty Include="@(DebJsonProperty)" /> + <_TargetInstallerRuntimeIdentifiers Include="$(InstallerRuntimeIdentifiers)" /> </ItemGroup> + + <PropertyGroup Condition="'$(InstallerRuntimeIdentifiers)' != '' and '$(InstallerRuntimeIdentifier)' != ''"> + <!-- Avoid building a project when none of the possible InstallerRuntimeIdentifiers is the current InstallerRuntimeIdentifier. --> + <_InstallerRidInInstallerRidList Condition="'%(_TargetInstallerRuntimeIdentifiers.Identity)' == '$(InstallerRuntimeIdentifier)'">true</_InstallerRidInInstallerRidList> + <SkipInstallerBuild Condition="'$(_InstallerRidInInstallerRidList)' != 'true'">true</SkipInstallerBuild> + </PropertyGroup> + <PropertyGroup Condition="'$(SkipBuild)' == 'true'"> + <SkipInstallerBuild>true</SkipInstallerBuild> + </PropertyGroup> </Target> - <!-- - Create RPM package. - --> - <Target Name="CreateRpm" - DependsOnTargets=" - _GetInstallerProperties; - _CreateInstallerLayout; - GetRpmInstallerJsonProperties" - Condition="'$(_FPMPresent)' == 'true'" - Returns="$(_InstallerFile)"> + <PropertyGroup> + <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps</BuildDependsOn> + <_GlobalPropertiesToRemoveForPublish> + GenerateCrossArchMsi; + GenerateMSI; + GeneratePkg; + GenerateDeb; + GenerateRpm; + IsShipping; + ComponentMsiFile; + InstallerRuntimeIdentifier; + InstallerTargetArchitecture; + CrossArchContentsArch + </_GlobalPropertiesToRemoveForPublish> + </PropertyGroup> + + <ItemGroup> + <_GlobalPropertiesToRemoveForPublish Include="$(_GlobalPropertiesToRemoveForPublish)" /> + </ItemGroup> + + <Target Name="_GetTargetOSArchInfo"> + <Error Condition="'$(InstallerRuntimeIdentifier)' == ''" + Text="An InstallerRuntimeIdentifier must be specified when building installers." /> <PropertyGroup> - <_ConfigJsonFile>$(_LayoutDirectory)rpm_config.json</_ConfigJsonFile> - <_RpmIntermediatesDir>$(_InstallerIntermediatesDir)out-rpm</_RpmIntermediatesDir> - - <!-- Copyright, Changelog --> - <_RpmTemplatesLayoutDir>$(_LayoutDirectory)templates/</_RpmTemplatesLayoutDir> + <TargetRuntimeOS>$(InstallerRuntimeIdentifier.Substring(0, $(InstallerRuntimeIdentifier.LastIndexOf('-'))))</TargetRuntimeOS> + <TargetArchitecture Condition="'$(TargetArchitecture)' == ''">$(InstallerRuntimeIdentifier.Substring($(InstallerRuntimeIdentifier.LastIndexOf('-'))).TrimStart('-'))</TargetArchitecture> + <InstallerTargetArchitecture Condition="'$(InstallerTargetArchitecture)' == ''">$(TargetArchitecture)</InstallerTargetArchitecture> </PropertyGroup> - <ItemGroup> - <_RpmTemplateFile Include="$(MSBuildThisFileDirectory)rpm_templates/**/*" /> + <CrossArchMsiToBuild Include="@(CrossArchSdkMsiInstallerArch)" Exclude="$(TargetArchitecture)" /> </ItemGroup> - - <Copy - SourceFiles="@(_RpmTemplateFile)" - DestinationFiles="@(_RpmTemplateFile->'$(_RpmTemplatesLayoutDir)%(RecursiveDir)%(Filename)%(Extension)')" /> - - <GenerateJsonObjectString - Properties="@(_CommonLinuxPackageProperty);@(_RpmJsonProperty)" - TargetFile="$(_ConfigJsonFile)" /> - - <MakeDir Directories="$(_RpmIntermediatesDir)" /> - - <!-- Call the task to build the pre-reqs (parameters, copyright, changelog) for calling the FPM tool --> - <BuildFPMToolPreReqs - InputDir="$(_LayoutDirectory)" - OutputDir="$(_RpmIntermediatesDir)" - PackageVersion="$(InstallerPackageVersion)" - ConfigJsonFile="$(_ConfigJsonFile)"> - <Output TaskParameter="FPMParameters" PropertyName="FPMCmdParameters" /> - </BuildFPMToolPreReqs> - - <Exec Command="fpm $(FPMCmdParameters)" WorkingDirectory="$(_RpmIntermediatesDir)" /> - - <!-- Copy package to output --> - <ItemGroup> - <GeneratedRpmFiles Include="$(_RpmIntermediatesDir)/*.rpm" /> - </ItemGroup> - - <Error Text="@(GeneratedRpmFiles->Count()) .rpm files generated." Condition="'@(GeneratedRpmFiles->Count())' != 1" /> - - <Copy SourceFiles="@(GeneratedRpmFiles)" - DestinationFiles="$(_InstallerFile)" - OverwriteReadOnlyFiles="True" - SkipUnchangedFiles="False" - UseHardlinksIfPossible="False" /> - - <Message Text="$(MSBuildProjectName) -> $(_InstallerFile)" Importance="high" /> - </Target> - - <Target Name="GetRpmInstallerJsonProperties" - DependsOnTargets="_GetCommonJsonProperties"> - <ItemGroup> - <_FpmDependenciesJsonEntry Include="@(LinuxPackageDependency->'{"package_name" : "%(Identity)", "package_version" : "%(Version)"}')" /> - </ItemGroup> - <ItemGroup> - <_RpmJsonProperty Include="vendor" String=".NET Foundation" /> - <_RpmJsonProperty Include="install_doc" String="/usr/share/doc/$(VersionedInstallerName)/" /> - <_RpmJsonProperty Include="rpm_dependencies" Object="[@(_FpmDependenciesJsonEntry,', ')]" /> - <_RpmJsonProperty Include="@(RpmJsonProperty)" /> - </ItemGroup> - </Target> - - <!-- - Create MSI installer, using WiX tools. - --> - <Target Name="CreateWixInstaller" - DependsOnTargets=" - _GetInstallerProperties; - RunLightLinker" - Returns="$(_OutInstallerFile)"> - <Error - Condition="'$(GenerateExeBundle)' == 'true' and '$(GenerateMSI)' == 'true'" - Text="GenerateExeBundle and GenerateMSI are both set, but only one can be created at a time." /> - - <Message Text="$(MSBuildProjectName) -> $(_OutInstallerFile)" Importance="high" /> - </Target> - - <!-- - Create MSI installers that install the current architecture's assets into the proper location - for a different architecture's SDK to find. - --> - <Target Name="CreateCrossArchWixInstaller" - DependsOnTargets="_GetTargetOSArchInfo" - Returns="@(_CrossArchMsi)"> - <MSBuild - Condition="'@(CrossArchMsiToBuild)' != ''" - Projects="$(MSBuildProjectFullPath)" - Targets="CreateWixInstaller" - Properties=" - InstallerTargetArchitecture=%(CrossArchMsiToBuild.Identity); - CrossArchContentsArch=$(TargetArchitecture); - GenerateMSI=true"> - <Output TaskParameter="TargetOutputs" ItemName="_CrossArchMsi" /> - </MSBuild> - </Target> - - <!-- - Create macOS pkg installer. - --> - <Target Name="CreatePkg" - DependsOnTargets=" - _GetInstallerProperties; - _CreateInstallerLayout" - Returns="@(_CreatedPkg)"> - - <!-- Copy files to layout. --> <PropertyGroup> - <_OutputPathRoot>$(IntermediateOutputPath)output/</_OutputPathRoot> - </PropertyGroup> - - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishToDisk" - Properties="OutputPath=$(_OutputPathRoot)" - RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> - <PropertyGroup> - <_MacOSVersionComponent Condition="'$(IncludeVersionInMacOSComponentName)' == 'true'">.$(ProductVersion)</_MacOSVersionComponent> - <_MacOSComponentName Condition="'$(_MacOSComponentName)' == ''">com.microsoft.dotnet.$(MacOSComponentNamePackType)$(_MacOSVersionComponent).component.osx.x64</_MacOSComponentName> - <_MacOSSharedInstallDir>/usr/local/share/dotnet</_MacOSSharedInstallDir> + <_osSupportsWixBasedInstallers Condition="$([MSBuild]::IsOsPlatform(Windows)) and '$(TargetRuntimeOS)' == 'win'">true</_osSupportsWixBasedInstallers> - <_pkgArgs></_pkgArgs> - <_pkgArgs>$(_pkgArgs) --root $(_OutputPathRoot)</_pkgArgs> - <_pkgArgs>$(_pkgArgs) --identifier $(_MacOSComponentName)</_pkgArgs> - <_pkgArgs>$(_pkgArgs) --version $(ProductVersion)</_pkgArgs> - <_pkgArgs>$(_pkgArgs) --install-location $(_MacOSSharedInstallDir)</_pkgArgs> - <_pkgArgs Condition="'$(MacOSScriptsDirectory)' != ''">$(_pkgArgs) --scripts $(MacOSScriptsDirectory)</_pkgArgs> - <_pkgArgs>$(_pkgArgs) $(_InstallerFile)</_pkgArgs> + <_osArchSupportsWixBasedInstallers>$(_osSupportsWixBasedInstallers)</_osArchSupportsWixBasedInstallers> + <_osArchSupportsWixBasedInstallers Condition="'$(TargetArchitecture)' == 'arm'">false</_osArchSupportsWixBasedInstallers> </PropertyGroup> - - <Exec Command="pkgbuild $(_pkgArgs)" /> - - <Message Text="$(MSBuildProjectName) -> $(_InstallerFile)" Importance="high" /> - <ItemGroup> - <_CreatedPkg Include="$(_InstallerFile)" Description="$(MacOSPackageDescription)" Title="$(ProductBrandName) ($(TargetArchitecture))" /> - </ItemGroup> </Target> - <!-- - Create installer layout. Used for RPM and Deb package creation. - --> - <Target Name="_CreateInstallerLayout"> + <Target Name="_GetVersionInfo"> <PropertyGroup> - <_LayoutDirectory>$(IntermediateOutputPath)installer/layoutDirectory/</_LayoutDirectory> - <_LayoutPackageRoot>$(_LayoutDirectory)package_root</_LayoutPackageRoot> - <_LayoutAbsolute>$(_LayoutDirectory)$</_LayoutAbsolute> - <_LayoutSamples>$(_LayoutDirectory)samples</_LayoutSamples> - <_LayoutDocs>$(_LayoutDirectory)docs</_LayoutDocs> + <IncludePreReleaseLabelInPackageVersion Condition="'$(DotNetFinalVersionKind)' != 'release'">true</IncludePreReleaseLabelInPackageVersion> + <IncludePreReleaseLabelInPackageVersion Condition="'$(SuppressFinalPackageVersion)' == 'true'">true</IncludePreReleaseLabelInPackageVersion> + <IncludePreReleaseLabelInPackageVersion Condition="'$(IsShipping)' != 'true'">true</IncludePreReleaseLabelInPackageVersion> </PropertyGroup> - - <RemoveDir Condition="Exists('$(_InstallerIntermediatesDir)')" Directories="$(_InstallerIntermediatesDir)" /> - <MakeDir Directories="$(_InstallerIntermediatesDir)" /> - - <!-- Create empty layout. --> - <RemoveDir Condition="Exists('$(_LayoutDirectory)')" Directories="$(_LayoutDirectory)" /> - <MakeDir Directories="$(_LayoutDirectory)" /> - <MakeDir Directories="$(_LayoutAbsolute)" /> - <MakeDir Directories="$(_LayoutPackageRoot)" /> - <MakeDir Directories="$(_LayoutSamples)" /> - <MakeDir Directories="$(_LayoutDocs)" /> - - <MSBuild Projects="$(MSBuildProjectFullPath)" - Targets="PublishToDisk" - Properties="OutputPath=$(_LayoutPackageRoot)" - RemoveProperties="@(_GlobalPropertiesToRemoveForPublish)" /> - - <Copy - SourceFiles="@(Manpage)" - DestinationFiles="@(Manpage->'$(_LayoutDocs)/%(RecursiveDir)%(Filename)%(Extension)')" /> </Target> - <!-- - Get common JSON properties. Used in the configuration JSON for both RPM and Debian packages. - --> - <Target Name="_GetCommonJsonProperties"> - <PropertyGroup> - <FullLicenseText>$([System.IO.File]::ReadAllText('$(LicenseFile)').Replace('%0A', '\n').Replace('"', '\"'))</FullLicenseText> - </PropertyGroup> + <Target Name="_GetProductBrandName" DependsOnTargets="_GetVersionInfo"> + <PropertyGroup + Condition=" + '$(ReleaseBrandSuffix)' == '' and + '$(PreReleaseVersionLabel)' != '' and + '$(PreReleaseVersionIteration)' != ''"> + <!-- Convert 'preview.7' to 'Preview 7'. + 'preview' will come from the pre-release version iteration and the numeric value + will be the PreReleaseVersionIteration. --> - <ItemGroup> - <_LinuxPackageReleaseProperty Include="package_version" String="1.0.0.0" /> - <_LinuxPackageReleaseProperty Include="package_revision" String="$(InstallerPackageRelease)" /> - <_LinuxPackageReleaseProperty Include="urgency" String="low" /> - <_LinuxPackageReleaseProperty Include="changelog_message" String="https://github.com/dotnet/core/tree/master/release-notes" /> - - <_LinuxPackageControlProperty Include="priority" String="standard" /> - <_LinuxPackageControlProperty Include="section" String="libs" /> - <_LinuxPackageControlProperty Include="architecture" String="amd64" /> - - <_LinuxPackageLicenseProperty Include="type" String="MIT and ASL 2.0 and BSD" /> - <_LinuxPackageLicenseProperty Include="full_text" String="$(FullLicenseText)" /> - </ItemGroup> + <ReleaseBrandSuffix>$(PreReleaseVersionLabel.Substring(0,1).ToUpperInvariant())</ReleaseBrandSuffix> + <ReleaseBrandSuffix>$(ReleaseBrandSuffix)$(PreReleaseVersionLabel.Substring(1))</ReleaseBrandSuffix> + <ReleaseBrandSuffix>$(ReleaseBrandSuffix) $(PreReleaseVersionIteration)</ReleaseBrandSuffix> + </PropertyGroup> - <GenerateJsonObjectString Properties="@(_LinuxPackageReleaseProperty)"> - <Output TaskParameter="Json" PropertyName="_JsonReleaseObject" /> - </GenerateJsonObjectString> - <GenerateJsonObjectString Properties="@(_LinuxPackageControlProperty)"> - <Output TaskParameter="Json" PropertyName="_JsonControlObject" /> - </GenerateJsonObjectString> - <GenerateJsonObjectString Properties="@(_LinuxPackageLicenseProperty)"> - <Output TaskParameter="Json" PropertyName="_JsonLicenseObject" /> - </GenerateJsonObjectString> + <Error + Text="When building installers a ProductBrandPrefix is required." + Condition="'$(ProductBrandPrefix)' == ''" /> + <Error + Text="When building installers a PackageBrandNameSuffix is required." + Condition="'$(PackageBrandNameSuffix)' == '' and '$(MSBuildProjectExtension)' != '.bundleproj'" /> + <Error + Text="When building a bundle installer, a BundleNameSuffix must be specified." + Condition="'$(BundleNameSuffix)' == '' and '$(MSBuildProjectExtension)' == '.bundleproj'" /> <PropertyGroup> - <_ShortDescription>$(MSBuildProjectName) $(InstallerPackageVersion)</_ShortDescription> - <_ShortDescription Condition="'$(UseBrandingNameInLinuxPackageDescription)' == 'true'">$(ProductBrandName)</_ShortDescription> + <ProductBrandSuffix>$(VersionPrefix)</ProductBrandSuffix> + <ProductBrandSuffix Condition="'$(ReleaseBrandSuffix)'!=''">$(VersionPrefix) $(ReleaseBrandSuffix)</ProductBrandSuffix> + <ProductBrandName Condition="'$(MSBuildProjectExtension)' == '.bundleproj'">$(ProductBrandPrefix) $(BundleNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> + <ProductBrandName Condition="'$(ProductBrandName)' == ''">$(ProductBrandPrefix) $(PackageBrandNameSuffix) - $(ProductBrandSuffix)</ProductBrandName> </PropertyGroup> - - <ItemGroup> - <_CommonLinuxPackageProperty Include="package_name" String="$(VersionedInstallerName)" /> - <_CommonLinuxPackageProperty Include="short_description" String="$(_ShortDescription)" /> - <_CommonLinuxPackageProperty Include="maintainer_name" String=".NET Team" /> - <_CommonLinuxPackageProperty Include="maintainer_email" String="dotnetpackages@dotnetfoundation.org" /> - <_CommonLinuxPackageProperty Include="install_root" String="/usr/share/dotnet" /> - <_CommonLinuxPackageProperty Include="long_description" String=".NET is a development platform that you can use to build command-line applications, microservices and modern websites. 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 (https://github.com/dotnet/core). We happily accept issues and PRs." /> - <_CommonLinuxPackageProperty Include="homepage" String="https://github.com/dotnet/core" /> - <_CommonLinuxPackageProperty Include="copyright" String="2017 Microsoft" /> - <_CommonLinuxPackageProperty Include="release" Object="$(_JsonReleaseObject)" /> - <_CommonLinuxPackageProperty Include="control" Object="$(_JsonControlObject)" /> - <_CommonLinuxPackageProperty Include="license" Object="$(_JsonLicenseObject)" /> - </ItemGroup> </Target> - + <PropertyGroup> - <BuildDependsOn>$(BuildDependsOn);_GetSkipInstallerBuildProps;GenerateInstallers</BuildDependsOn> + <InstallerRuntimeIdentifiers Condition="'$(InstallerRuntimeIdentifiers)' == ''">$(RuntimeIdentifiers)</InstallerRuntimeIdentifiers> + <InstallerRuntimeIdentifier Condition="'$(InstallerRuntimeIdentifier)' == ''">$(RuntimeIdentifier)</InstallerRuntimeIdentifier> </PropertyGroup> + + <Import Project="$(MSBuildThisFileDirectory)installer.singlerid.targets" + Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' != ''" /> + <Import Project="$(MSBuildThisFileDirectory)installer.multirid.targets" + Condition="'$(MSBuildProjectExtension)' != '.bundleproj' and '$(GenerateInstallers)' == 'true' and '$(InstallerRuntimeIdentifier)' == ''" /> + <Import Project="$(MSBuildThisFileDirectory)bundle.targets" + Condition="'$(MSBuildProjectExtension)' == '.bundleproj'" /> </Project>