aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2020-07-21 14:31:53 -0700
committerRob Mensching <rob@firegiant.com>2020-07-21 14:41:12 -0700
commitb62a7a0beb7ceb7987de28ec768c7814cadb83b9 (patch)
tree69a9183a3182334f0d48a39ab8e411ee3fc3aecd /src/WixToolset.Core
parent414c07f7adce9c9fd0132ab0fade0267f743f665 (diff)
downloadwix-b62a7a0beb7ceb7987de28ec768c7814cadb83b9.tar.gz
wix-b62a7a0beb7ceb7987de28ec768c7814cadb83b9.tar.bz2
wix-b62a7a0beb7ceb7987de28ec768c7814cadb83b9.zip
Support implicit standard directory reference and "3264" platform folders
Completes wixtoolset/issues#5798 and wixtoolset/issues#5835
Diffstat (limited to 'src/WixToolset.Core')
-rw-r--r--src/WixToolset.Core/Compiler.cs3
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/PathResolver.cs51
-rw-r--r--src/WixToolset.Core/Link/ResolveReferencesCommand.cs25
-rw-r--r--src/WixToolset.Core/Link/SymbolWithSection.cs91
-rw-r--r--src/WixToolset.Core/Linker.cs22
5 files changed, 159 insertions, 33 deletions
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
4279 this.Core.AddInlineDirectoryId(inlineSyntax, id.Id); 4279 this.Core.AddInlineDirectoryId(inlineSyntax, id.Id);
4280 } 4280 }
4281 } 4281 }
4282 4282 else if ("TARGETDIR".Equals(id.Id, StringComparison.Ordinal) && !("SourceDir".Equals(name, StringComparison.Ordinal) && shortName == null && shortSourceName == null && sourceName == null))
4283 if ("TARGETDIR".Equals(id.Id, StringComparison.Ordinal) && !("SourceDir".Equals(name, StringComparison.Ordinal) && shortName == null && shortSourceName == null && sourceName == null))
4284 { 4283 {
4285 this.Core.Write(ErrorMessages.IllegalTargetDirDefaultDir(sourceLineNumbers, name)); 4284 this.Core.Write(ErrorMessages.IllegalTargetDirDefaultDir(sourceLineNumbers, name));
4286 } 4285 }
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
12 12
13 internal class PathResolver : IPathResolver 13 internal class PathResolver : IPathResolver
14 { 14 {
15 public string GetDirectoryPath(Dictionary<string, IResolvedDirectory> directories, Dictionary<string, string> componentIdGenSeeds, string directory, bool canonicalize) 15 public string GetCanonicalDirectoryPath(Dictionary<string, IResolvedDirectory> directories, Dictionary<string, string> componentIdGenSeeds, string directory, Platform platform)
16 { 16 {
17 if (!directories.TryGetValue(directory, out var resolvedDirectory)) 17 if (!directories.TryGetValue(directory, out var resolvedDirectory))
18 { 18 {
@@ -25,19 +25,13 @@ namespace WixToolset.Core.ExtensibilityServices
25 { 25 {
26 resolvedDirectory.Path = componentIdGenSeeds[directory]; 26 resolvedDirectory.Path = componentIdGenSeeds[directory];
27 } 27 }
28 else if (canonicalize && WindowsInstallerStandard.IsStandardDirectory(directory)) 28 else if (WindowsInstallerStandard.IsStandardDirectory(directory))
29 { 29 {
30 // when canonicalization is on, standard directories are treated equally 30 resolvedDirectory.Path = WindowsInstallerStandard.GetPlatformSpecificDirectoryId(directory, platform);
31 resolvedDirectory.Path = directory;
32 } 31 }
33 else 32 else
34 { 33 {
35 string name = resolvedDirectory.Name; 34 var name = resolvedDirectory.Name?.ToLowerInvariant();
36
37 if (canonicalize)
38 {
39 name = name?.ToLowerInvariant();
40 }
41 35
42 if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent)) 36 if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent))
43 { 37 {
@@ -45,7 +39,7 @@ namespace WixToolset.Core.ExtensibilityServices
45 } 39 }
46 else 40 else
47 { 41 {
48 var parentPath = this.GetDirectoryPath(directories, componentIdGenSeeds, resolvedDirectory.DirectoryParent, canonicalize); 42 var parentPath = this.GetCanonicalDirectoryPath(directories, componentIdGenSeeds, resolvedDirectory.DirectoryParent, platform);
49 43
50 if (null != resolvedDirectory.Name) 44 if (null != resolvedDirectory.Name)
51 { 45 {
@@ -62,6 +56,39 @@ namespace WixToolset.Core.ExtensibilityServices
62 return resolvedDirectory.Path; 56 return resolvedDirectory.Path;
63 } 57 }
64 58
59 public string GetDirectoryPath(Dictionary<string, IResolvedDirectory> directories, string directory)
60 {
61 if (!directories.TryGetValue(directory, out var resolvedDirectory))
62 {
63 throw new WixException(ErrorMessages.ExpectedDirectory(directory));
64 }
65
66 if (null == resolvedDirectory.Path)
67 {
68 var name = resolvedDirectory.Name;
69
70 if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent))
71 {
72 resolvedDirectory.Path = name;
73 }
74 else
75 {
76 var parentPath = this.GetDirectoryPath(directories, resolvedDirectory.DirectoryParent);
77
78 if (null != resolvedDirectory.Name)
79 {
80 resolvedDirectory.Path = Path.Combine(parentPath, name);
81 }
82 else
83 {
84 resolvedDirectory.Path = parentPath;
85 }
86 }
87 }
88
89 return resolvedDirectory.Path;
90 }
91
65 public string GetFileSourcePath(Dictionary<string, IResolvedDirectory> directories, string directoryId, string fileName, bool compressed, bool useLongName) 92 public string GetFileSourcePath(Dictionary<string, IResolvedDirectory> directories, string directoryId, string fileName, bool compressed, bool useLongName)
66 { 93 {
67 var fileSourcePath = Common.GetName(fileName, true, useLongName); 94 var fileSourcePath = Common.GetName(fileName, true, useLongName);
@@ -75,7 +102,7 @@ namespace WixToolset.Core.ExtensibilityServices
75 { 102 {
76 // Get the relative path of where we want the file to be layed out as specified 103 // Get the relative path of where we want the file to be layed out as specified
77 // in the Directory table. 104 // in the Directory table.
78 var directoryPath = this.GetDirectoryPath(directories, null, directoryId, false); 105 var directoryPath = this.GetDirectoryPath(directories, directoryId);
79 fileSourcePath = Path.Combine(directoryPath, fileSourcePath); 106 fileSourcePath = Path.Combine(directoryPath, fileSourcePath);
80 } 107 }
81 108
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
72 continue; 72 continue;
73 } 73 }
74 74
75 if (!this.symbolsWithSections.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbolWithSection)) 75 // See if the symbol (and any of its duplicates) are appropriately accessible.
76 { 76 if (this.symbolsWithSections.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbolWithSection))
77 this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName));
78 }
79 else // see if the symbol (and any of its duplicates) are appropriately accessible.
80 { 77 {
81 var accessible = this.DetermineAccessibleSymbols(section, symbolWithSection); 78 var accessible = this.DetermineAccessibleSymbols(section, symbolWithSection);
82 if (!accessible.Any()) 79 if (accessible.Count == 1)
83 {
84 this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbolWithSection.Access));
85 }
86 else if (1 == accessible.Count)
87 { 80 {
88 var accessibleSymbol = accessible[0]; 81 var accessibleSymbol = accessible[0];
89 this.referencedSymbols.Add(accessibleSymbol); 82 if (this.referencedSymbols.Add(accessibleSymbol) && null != accessibleSymbol.Section)
90
91 if (null != accessibleSymbol.Section)
92 { 83 {
93 this.RecursivelyResolveReferences(accessibleSymbol.Section); 84 this.RecursivelyResolveReferences(accessibleSymbol.Section);
94 } 85 }
95 } 86 }
87 else if (accessible.Count == 0)
88 {
89 this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbolWithSection.Access));
90 }
96 else // display errors for the duplicate symbols. 91 else // display errors for the duplicate symbols.
97 { 92 {
98 var accessibleSymbol = accessible[0]; 93 var accessibleSymbol = accessible[0];
@@ -113,6 +108,10 @@ namespace WixToolset.Core.Link
113 } 108 }
114 } 109 }
115 } 110 }
111 else
112 {
113 this.Messaging.Write(ErrorMessages.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName));
114 }
116 } 115 }
117 } 116 }
118 117
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 @@
1// 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.
2
3namespace WixToolset.Core.Link
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Data;
9
10 /// <summary>
11 /// Symbol with section representing a single unique symbol.
12 /// </summary>
13 internal class SymbolWithSection
14 {
15 private HashSet<SymbolWithSection> possibleConflicts;
16 private HashSet<SymbolWithSection> redundants;
17
18 /// <summary>
19 /// Creates a symbol for a symbol.
20 /// </summary>
21 /// <param name="symbol">Symbol for the symbol</param>
22 public SymbolWithSection(IntermediateSection section, IntermediateSymbol symbol)
23 {
24 this.Symbol = symbol;
25 this.Section = section;
26 this.Name = String.Concat(this.Symbol.Definition.Name, ":", this.Symbol.Id.Id);
27 }
28
29 /// <summary>
30 /// Gets the accessibility of the symbol which is a direct reflection of the accessibility of the row's accessibility.
31 /// </summary>
32 /// <value>Accessbility of the symbol.</value>
33 public AccessModifier Access => this.Symbol.Id.Access;
34
35 /// <summary>
36 /// Gets the name of the symbol.
37 /// </summary>
38 /// <value>Name of the symbol.</value>
39 public string Name { get; }
40
41 /// <summary>
42 /// Gets the symbol for this symbol.
43 /// </summary>
44 /// <value>Symbol for this symbol.</value>
45 public IntermediateSymbol Symbol { get; }
46
47 /// <summary>
48 /// Gets the section for the symbol.
49 /// </summary>
50 /// <value>Section for the symbol.</value>
51 public IntermediateSection Section { get; }
52
53 /// <summary>
54 /// Gets any duplicates of this symbol with sections that are possible conflicts.
55 /// </summary>
56 public IEnumerable<SymbolWithSection> PossiblyConflicts => this.possibleConflicts ?? Enumerable.Empty<SymbolWithSection>();
57
58 /// <summary>
59 /// Gets any duplicates of this symbol with sections that are redundant.
60 /// </summary>
61 public IEnumerable<SymbolWithSection> Redundants => this.redundants ?? Enumerable.Empty<SymbolWithSection>();
62
63 /// <summary>
64 /// Adds a duplicate symbol with sections that is a possible conflict.
65 /// </summary>
66 /// <param name="symbolWithSection">Symbol with section that is a possible conflict of this symbol.</param>
67 public void AddPossibleConflict(SymbolWithSection symbolWithSection)
68 {
69 if (null == this.possibleConflicts)
70 {
71 this.possibleConflicts = new HashSet<SymbolWithSection>();
72 }
73
74 this.possibleConflicts.Add(symbolWithSection);
75 }
76
77 /// <summary>
78 /// Adds a duplicate symbol that is redundant.
79 /// </summary>
80 /// <param name="symbolWithSection">Symbol with section that is redundant of this symbol.</param>
81 public void AddRedundant(SymbolWithSection symbolWithSection)
82 {
83 if (null == this.redundants)
84 {
85 this.redundants = new HashSet<SymbolWithSection>();
86 }
87
88 this.redundants.Add(symbolWithSection);
89 }
90 }
91}
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
149 throw new WixException(ErrorMessages.MissingEntrySection(this.Context.ExpectedOutputType.ToString())); 149 throw new WixException(ErrorMessages.MissingEntrySection(this.Context.ExpectedOutputType.ToString()));
150 } 150 }
151 151
152 // Add the missing standard action symbols. 152 // Add the missing standard action and directory symbols.
153 this.LoadStandardActions(find.EntrySection, find.SymbolsByName); 153 this.LoadStandardSymbols(find.SymbolsByName);
154 154
155 // Resolve the symbol references to find the set of sections we care about for linking. 155 // Resolve the symbol references to find the set of sections we care about for linking.
156 // Of course, we start with the entry section (that's how it got its name after all). 156 // Of course, we start with the entry section (that's how it got its name after all).
157 var resolve = new ResolveReferencesCommand(this.Messaging, find.EntrySection, find.SymbolsByName); 157 var resolve = new ResolveReferencesCommand(this.Messaging, find.EntrySection, find.SymbolsByName);
158
159 resolve.Execute(); 158 resolve.Execute();
160 159
161 if (this.Messaging.EncounteredError) 160 if (this.Messaging.EncounteredError)
@@ -732,14 +731,14 @@ namespace WixToolset.Core
732#endif 731#endif
733 732
734 /// <summary> 733 /// <summary>
735 /// Load the standard action symbols. 734 /// Load the standard action and directory symbols.
736 /// </summary> 735 /// </summary>
737 /// <param name="symbolsByName">Collection of symbols.</param> 736 /// <param name="symbolsByName">Collection of symbols.</param>
738 private void LoadStandardActions(IntermediateSection section, IDictionary<string, SymbolWithSection> symbolsByName) 737 private void LoadStandardSymbols(IDictionary<string, SymbolWithSection> symbolsByName)
739 { 738 {
740 foreach (var actionSymbol in WindowsInstallerStandard.StandardActions()) 739 foreach (var actionSymbol in WindowsInstallerStandard.StandardActions())
741 { 740 {
742 var symbolWithSection = new SymbolWithSection(section, actionSymbol); 741 var symbolWithSection = new SymbolWithSection(null, actionSymbol);
743 742
744 // If the action's symbol has not already been defined (i.e. overriden by the user), add it now. 743 // If the action's symbol has not already been defined (i.e. overriden by the user), add it now.
745 if (!symbolsByName.ContainsKey(symbolWithSection.Name)) 744 if (!symbolsByName.ContainsKey(symbolWithSection.Name))
@@ -747,6 +746,17 @@ namespace WixToolset.Core
747 symbolsByName.Add(symbolWithSection.Name, symbolWithSection); 746 symbolsByName.Add(symbolWithSection.Name, symbolWithSection);
748 } 747 }
749 } 748 }
749
750 foreach (var directorySymbol in WindowsInstallerStandard.StandardDirectories())
751 {
752 var symbolWithSection = new SymbolWithSection(null, directorySymbol);
753
754 // If the directory's symbol has not already been defined (i.e. overriden by the user), add it now.
755 if (!symbolsByName.ContainsKey(symbolWithSection.Name))
756 {
757 symbolsByName.Add(symbolWithSection.Name, symbolWithSection);
758 }
759 }
750 } 760 }
751 761
752 /// <summary> 762 /// <summary>