From b62a7a0beb7ceb7987de28ec768c7814cadb83b9 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 21 Jul 2020 14:31:53 -0700 Subject: Support implicit standard directory reference and "3264" platform folders Completes wixtoolset/issues#5798 and wixtoolset/issues#5835 --- src/WixToolset.Core/Compiler.cs | 3 +- .../ExtensibilityServices/PathResolver.cs | 51 +++++++++--- .../Link/ResolveReferencesCommand.cs | 25 +++--- src/WixToolset.Core/Link/SymbolWithSection.cs | 91 ++++++++++++++++++++++ src/WixToolset.Core/Linker.cs | 22 ++++-- 5 files changed, 159 insertions(+), 33 deletions(-) create mode 100644 src/WixToolset.Core/Link/SymbolWithSection.cs (limited to 'src/WixToolset.Core') diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs index c504e96f..c641bceb 100644 --- a/src/WixToolset.Core/Compiler.cs +++ b/src/WixToolset.Core/Compiler.cs @@ -4279,8 +4279,7 @@ namespace WixToolset.Core this.Core.AddInlineDirectoryId(inlineSyntax, id.Id); } } - - if ("TARGETDIR".Equals(id.Id, StringComparison.Ordinal) && !("SourceDir".Equals(name, StringComparison.Ordinal) && shortName == null && shortSourceName == null && sourceName == null)) + else if ("TARGETDIR".Equals(id.Id, StringComparison.Ordinal) && !("SourceDir".Equals(name, StringComparison.Ordinal) && shortName == null && shortSourceName == null && sourceName == null)) { this.Core.Write(ErrorMessages.IllegalTargetDirDefaultDir(sourceLineNumbers, name)); } diff --git a/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs b/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs index 15cd4fc9..72be2bcb 100644 --- a/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs +++ b/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs @@ -12,7 +12,7 @@ namespace WixToolset.Core.ExtensibilityServices internal class PathResolver : IPathResolver { - public string GetDirectoryPath(Dictionary directories, Dictionary componentIdGenSeeds, string directory, bool canonicalize) + public string GetCanonicalDirectoryPath(Dictionary directories, Dictionary componentIdGenSeeds, string directory, Platform platform) { if (!directories.TryGetValue(directory, out var resolvedDirectory)) { @@ -25,19 +25,13 @@ namespace WixToolset.Core.ExtensibilityServices { resolvedDirectory.Path = componentIdGenSeeds[directory]; } - else if (canonicalize && WindowsInstallerStandard.IsStandardDirectory(directory)) + else if (WindowsInstallerStandard.IsStandardDirectory(directory)) { - // when canonicalization is on, standard directories are treated equally - resolvedDirectory.Path = directory; + resolvedDirectory.Path = WindowsInstallerStandard.GetPlatformSpecificDirectoryId(directory, platform); } else { - string name = resolvedDirectory.Name; - - if (canonicalize) - { - name = name?.ToLowerInvariant(); - } + var name = resolvedDirectory.Name?.ToLowerInvariant(); if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent)) { @@ -45,7 +39,7 @@ namespace WixToolset.Core.ExtensibilityServices } else { - var parentPath = this.GetDirectoryPath(directories, componentIdGenSeeds, resolvedDirectory.DirectoryParent, canonicalize); + var parentPath = this.GetCanonicalDirectoryPath(directories, componentIdGenSeeds, resolvedDirectory.DirectoryParent, platform); if (null != resolvedDirectory.Name) { @@ -62,6 +56,39 @@ namespace WixToolset.Core.ExtensibilityServices return resolvedDirectory.Path; } + public string GetDirectoryPath(Dictionary directories, string directory) + { + if (!directories.TryGetValue(directory, out var resolvedDirectory)) + { + throw new WixException(ErrorMessages.ExpectedDirectory(directory)); + } + + if (null == resolvedDirectory.Path) + { + var name = resolvedDirectory.Name; + + if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent)) + { + resolvedDirectory.Path = name; + } + else + { + var parentPath = this.GetDirectoryPath(directories, resolvedDirectory.DirectoryParent); + + if (null != resolvedDirectory.Name) + { + resolvedDirectory.Path = Path.Combine(parentPath, name); + } + else + { + resolvedDirectory.Path = parentPath; + } + } + } + + return resolvedDirectory.Path; + } + public string GetFileSourcePath(Dictionary directories, string directoryId, string fileName, bool compressed, bool useLongName) { var fileSourcePath = Common.GetName(fileName, true, useLongName); @@ -75,7 +102,7 @@ namespace WixToolset.Core.ExtensibilityServices { // Get the relative path of where we want the file to be layed out as specified // in the Directory table. - var directoryPath = this.GetDirectoryPath(directories, null, directoryId, false); + var directoryPath = this.GetDirectoryPath(directories, directoryId); fileSourcePath = Path.Combine(directoryPath, fileSourcePath); } diff --git a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs index d2be0699..90b61e8b 100644 --- a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs +++ b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs @@ -72,27 +72,22 @@ namespace WixToolset.Core.Link continue; } - if (!this.symbolsWithSections.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbolWithSection)) - { - this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName)); - } - else // see if the symbol (and any of its duplicates) are appropriately accessible. + // See if the symbol (and any of its duplicates) are appropriately accessible. + if (this.symbolsWithSections.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbolWithSection)) { var accessible = this.DetermineAccessibleSymbols(section, symbolWithSection); - if (!accessible.Any()) - { - this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbolWithSection.Access)); - } - else if (1 == accessible.Count) + if (accessible.Count == 1) { var accessibleSymbol = accessible[0]; - this.referencedSymbols.Add(accessibleSymbol); - - if (null != accessibleSymbol.Section) + if (this.referencedSymbols.Add(accessibleSymbol) && null != accessibleSymbol.Section) { this.RecursivelyResolveReferences(accessibleSymbol.Section); } } + else if (accessible.Count == 0) + { + this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbolWithSection.Access)); + } else // display errors for the duplicate symbols. { var accessibleSymbol = accessible[0]; @@ -113,6 +108,10 @@ namespace WixToolset.Core.Link } } } + else + { + this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName)); + } } } diff --git a/src/WixToolset.Core/Link/SymbolWithSection.cs b/src/WixToolset.Core/Link/SymbolWithSection.cs new file mode 100644 index 00000000..c8934d0f --- /dev/null +++ b/src/WixToolset.Core/Link/SymbolWithSection.cs @@ -0,0 +1,91 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Core.Link +{ + using System; + using System.Collections.Generic; + using System.Linq; + using WixToolset.Data; + + /// + /// Symbol with section representing a single unique symbol. + /// + internal class SymbolWithSection + { + private HashSet possibleConflicts; + private HashSet redundants; + + /// + /// Creates a symbol for a symbol. + /// + /// Symbol for the symbol + public SymbolWithSection(IntermediateSection section, IntermediateSymbol symbol) + { + this.Symbol = symbol; + this.Section = section; + this.Name = String.Concat(this.Symbol.Definition.Name, ":", this.Symbol.Id.Id); + } + + /// + /// Gets the accessibility of the symbol which is a direct reflection of the accessibility of the row's accessibility. + /// + /// Accessbility of the symbol. + public AccessModifier Access => this.Symbol.Id.Access; + + /// + /// Gets the name of the symbol. + /// + /// Name of the symbol. + public string Name { get; } + + /// + /// Gets the symbol for this symbol. + /// + /// Symbol for this symbol. + public IntermediateSymbol Symbol { get; } + + /// + /// Gets the section for the symbol. + /// + /// Section for the symbol. + public IntermediateSection Section { get; } + + /// + /// Gets any duplicates of this symbol with sections that are possible conflicts. + /// + public IEnumerable PossiblyConflicts => this.possibleConflicts ?? Enumerable.Empty(); + + /// + /// Gets any duplicates of this symbol with sections that are redundant. + /// + public IEnumerable Redundants => this.redundants ?? Enumerable.Empty(); + + /// + /// Adds a duplicate symbol with sections that is a possible conflict. + /// + /// Symbol with section that is a possible conflict of this symbol. + public void AddPossibleConflict(SymbolWithSection symbolWithSection) + { + if (null == this.possibleConflicts) + { + this.possibleConflicts = new HashSet(); + } + + this.possibleConflicts.Add(symbolWithSection); + } + + /// + /// Adds a duplicate symbol that is redundant. + /// + /// Symbol with section that is redundant of this symbol. + public void AddRedundant(SymbolWithSection symbolWithSection) + { + if (null == this.redundants) + { + this.redundants = new HashSet(); + } + + this.redundants.Add(symbolWithSection); + } + } +} diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs index cdefa5c7..1cfd085d 100644 --- a/src/WixToolset.Core/Linker.cs +++ b/src/WixToolset.Core/Linker.cs @@ -149,13 +149,12 @@ namespace WixToolset.Core throw new WixException(ErrorMessages.MissingEntrySection(this.Context.ExpectedOutputType.ToString())); } - // Add the missing standard action symbols. - this.LoadStandardActions(find.EntrySection, find.SymbolsByName); + // Add the missing standard action and directory symbols. + this.LoadStandardSymbols(find.SymbolsByName); // Resolve the symbol references to find the set of sections we care about for linking. // Of course, we start with the entry section (that's how it got its name after all). var resolve = new ResolveReferencesCommand(this.Messaging, find.EntrySection, find.SymbolsByName); - resolve.Execute(); if (this.Messaging.EncounteredError) @@ -732,14 +731,14 @@ namespace WixToolset.Core #endif /// - /// Load the standard action symbols. + /// Load the standard action and directory symbols. /// /// Collection of symbols. - private void LoadStandardActions(IntermediateSection section, IDictionary symbolsByName) + private void LoadStandardSymbols(IDictionary symbolsByName) { foreach (var actionSymbol in WindowsInstallerStandard.StandardActions()) { - var symbolWithSection = new SymbolWithSection(section, actionSymbol); + var symbolWithSection = new SymbolWithSection(null, actionSymbol); // If the action's symbol has not already been defined (i.e. overriden by the user), add it now. if (!symbolsByName.ContainsKey(symbolWithSection.Name)) @@ -747,6 +746,17 @@ namespace WixToolset.Core symbolsByName.Add(symbolWithSection.Name, symbolWithSection); } } + + foreach (var directorySymbol in WindowsInstallerStandard.StandardDirectories()) + { + var symbolWithSection = new SymbolWithSection(null, directorySymbol); + + // If the directory's symbol has not already been defined (i.e. overriden by the user), add it now. + if (!symbolsByName.ContainsKey(symbolWithSection.Name)) + { + symbolsByName.Add(symbolWithSection.Name, symbolWithSection); + } + } } /// -- cgit v1.2.3-55-g6feb