aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-08-07 11:51:01 -0700
committerRob Mensching <rob@firegiant.com>2022-08-07 12:40:54 -0700
commit11f6b34b97809da414d6368155e70125b582565f (patch)
tree4380e8af7365425d9f40046621d9af556ac5f9b5
parent5c601223834cb8571d31232c7524ed3b6ed786e2 (diff)
downloadwix-11f6b34b97809da414d6368155e70125b582565f.tar.gz
wix-11f6b34b97809da414d6368155e70125b582565f.tar.bz2
wix-11f6b34b97809da414d6368155e70125b582565f.zip
Add intermediate folder and output path to all contexts
Extensions sometimes need to generate files and lay them out relative to the final output path. Provide that context to all extensions so they can use the correct intermediate folder and output path.
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/ICommandLineContext.cs13
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs10
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/ILayoutContext.cs5
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/ILibraryContext.cs10
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/ILinkContext.cs10
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/IPreprocessContext.cs10
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/IResolveContext.cs5
-rw-r--r--src/wix/WixToolset.Core/CommandLine/BuildCommand.cs45
-rw-r--r--src/wix/WixToolset.Core/CompileContext.cs4
-rw-r--r--src/wix/WixToolset.Core/LayoutContext.cs2
-rw-r--r--src/wix/WixToolset.Core/LibraryContext.cs4
-rw-r--r--src/wix/WixToolset.Core/LinkContext.cs4
-rw-r--r--src/wix/WixToolset.Core/PreprocessContext.cs4
-rw-r--r--src/wix/WixToolset.Core/ResolveContext.cs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/LinkerFixture.cs2
15 files changed, 115 insertions, 15 deletions
diff --git a/src/api/wix/WixToolset.Extensibility/Data/ICommandLineContext.cs b/src/api/wix/WixToolset.Extensibility/Data/ICommandLineContext.cs
index d8c9469e..595fc996 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/ICommandLineContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/ICommandLineContext.cs
@@ -5,13 +5,24 @@ namespace WixToolset.Extensibility.Data
5 using System; 5 using System;
6 using WixToolset.Extensibility.Services; 6 using WixToolset.Extensibility.Services;
7 7
8#pragma warning disable 1591 // TODO: add documentation 8 /// <summary>
9 /// Command-line context.
10 /// </summary>
9 public interface ICommandLineContext 11 public interface ICommandLineContext
10 { 12 {
13 /// <summary>
14 /// Service provider.
15 /// </summary>
11 IServiceProvider ServiceProvider { get; } 16 IServiceProvider ServiceProvider { get; }
12 17
18 /// <summary>
19 /// Extension manager.
20 /// </summary>
13 IExtensionManager ExtensionManager { get; set; } 21 IExtensionManager ExtensionManager { get; set; }
14 22
23 /// <summary>
24 /// Command-line arguments.
25 /// </summary>
15 ICommandLineArguments Arguments { get; set; } 26 ICommandLineArguments Arguments { get; set; }
16 } 27 }
17} 28}
diff --git a/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs b/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs
index 2ee8f2a1..7006fde8 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs
@@ -29,6 +29,16 @@ namespace WixToolset.Extensibility.Data
29 IReadOnlyCollection<ICompilerExtension> Extensions { get; set; } 29 IReadOnlyCollection<ICompilerExtension> Extensions { get; set; }
30 30
31 /// <summary> 31 /// <summary>
32 /// Intermediate folder.
33 /// </summary>
34 string IntermediateFolder { get; set; }
35
36 /// <summary>
37 /// Output path.
38 /// </summary>
39 string OutputPath { get; set; }
40
41 /// <summary>
32 /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. 42 /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements.
33 /// </summary> 43 /// </summary>
34 /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value> 44 /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value>
diff --git a/src/api/wix/WixToolset.Extensibility/Data/ILayoutContext.cs b/src/api/wix/WixToolset.Extensibility/Data/ILayoutContext.cs
index 981ed38e..8ff26365 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/ILayoutContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/ILayoutContext.cs
@@ -37,6 +37,11 @@ namespace WixToolset.Extensibility.Data
37 string IntermediateFolder { get; set; } 37 string IntermediateFolder { get; set; }
38 38
39 /// <summary> 39 /// <summary>
40 /// Output path.
41 /// </summary>
42 string OutputPath { get; set; }
43
44 /// <summary>
40 /// File to capture list of content, built output and copied output files. 45 /// File to capture list of content, built output and copied output files.
41 /// </summary> 46 /// </summary>
42 string TrackingFile { get; set; } 47 string TrackingFile { get; set; }
diff --git a/src/api/wix/WixToolset.Extensibility/Data/ILibraryContext.cs b/src/api/wix/WixToolset.Extensibility/Data/ILibraryContext.cs
index 208b6f73..f3c4db6e 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/ILibraryContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/ILibraryContext.cs
@@ -43,11 +43,21 @@ namespace WixToolset.Extensibility.Data
43 IReadOnlyCollection<Localization> Localizations { get; set; } 43 IReadOnlyCollection<Localization> Localizations { get; set; }
44 44
45 /// <summary> 45 /// <summary>
46 /// Intermediate folder.
47 /// </summary>
48 string IntermediateFolder { get; set; }
49
50 /// <summary>
46 /// Collection of intermediates to include in the library. 51 /// Collection of intermediates to include in the library.
47 /// </summary> 52 /// </summary>
48 IReadOnlyCollection<Intermediate> Intermediates { get; set; } 53 IReadOnlyCollection<Intermediate> Intermediates { get; set; }
49 54
50 /// <summary> 55 /// <summary>
56 /// Output path.
57 /// </summary>
58 string OutputPath { get; set; }
59
60 /// <summary>
51 /// Cancellation token. 61 /// Cancellation token.
52 /// </summary> 62 /// </summary>
53 CancellationToken CancellationToken { get; set; } 63 CancellationToken CancellationToken { get; set; }
diff --git a/src/api/wix/WixToolset.Extensibility/Data/ILinkContext.cs b/src/api/wix/WixToolset.Extensibility/Data/ILinkContext.cs
index d56866f7..8556d9eb 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/ILinkContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/ILinkContext.cs
@@ -33,11 +33,21 @@ namespace WixToolset.Extensibility.Data
33 OutputType ExpectedOutputType { get; set; } 33 OutputType ExpectedOutputType { get; set; }
34 34
35 /// <summary> 35 /// <summary>
36 /// Intermediate folder.
37 /// </summary>
38 string IntermediateFolder { get; set; }
39
40 /// <summary>
36 /// Collection of intermediates to link. 41 /// Collection of intermediates to link.
37 /// </summary> 42 /// </summary>
38 IReadOnlyCollection<Intermediate> Intermediates { get; set; } 43 IReadOnlyCollection<Intermediate> Intermediates { get; set; }
39 44
40 /// <summary> 45 /// <summary>
46 /// Output path.
47 /// </summary>
48 string OutputPath { get; set; }
49
50 /// <summary>
41 /// Symbol definition creator used to load extension data. 51 /// Symbol definition creator used to load extension data.
42 /// </summary> 52 /// </summary>
43 ISymbolDefinitionCreator SymbolDefinitionCreator { get; set; } 53 ISymbolDefinitionCreator SymbolDefinitionCreator { get; set; }
diff --git a/src/api/wix/WixToolset.Extensibility/Data/IPreprocessContext.cs b/src/api/wix/WixToolset.Extensibility/Data/IPreprocessContext.cs
index 69057c33..39e56f7c 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/IPreprocessContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/IPreprocessContext.cs
@@ -28,6 +28,16 @@ namespace WixToolset.Extensibility.Data
28 IReadOnlyCollection<string> IncludeSearchPaths { get; set; } 28 IReadOnlyCollection<string> IncludeSearchPaths { get; set; }
29 29
30 /// <summary> 30 /// <summary>
31 /// Intermediate folder.
32 /// </summary>
33 string IntermediateFolder { get; set; }
34
35 /// <summary>
36 /// Output path.
37 /// </summary>
38 string OutputPath { get; set; }
39
40 /// <summary>
31 /// Gets the platform which the compiler will use when defaulting 64-bit attributes and elements. 41 /// Gets the platform which the compiler will use when defaulting 64-bit attributes and elements.
32 /// </summary> 42 /// </summary>
33 /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value> 43 /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value>
diff --git a/src/api/wix/WixToolset.Extensibility/Data/IResolveContext.cs b/src/api/wix/WixToolset.Extensibility/Data/IResolveContext.cs
index 63159ccb..bec689ba 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/IResolveContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/IResolveContext.cs
@@ -58,6 +58,11 @@ namespace WixToolset.Extensibility.Data
58 bool AllowUnresolvedVariables { get; set; } 58 bool AllowUnresolvedVariables { get; set; }
59 59
60 /// <summary> 60 /// <summary>
61 /// Output path.
62 /// </summary>
63 string OutputPath { get; set; }
64
65 /// <summary>
61 /// Cancellation token. 66 /// Cancellation token.
62 /// </summary> 67 /// </summary>
63 CancellationToken CancellationToken { get; set; } 68 CancellationToken CancellationToken { get; set; }
diff --git a/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs b/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
index f291fa8c..e63c727c 100644
--- a/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
+++ b/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
@@ -49,6 +49,8 @@ namespace WixToolset.Core.CommandLine
49 49
50 private string IntermediateFolder { get; set; } 50 private string IntermediateFolder { get; set; }
51 51
52 private string OutputPath { get; set; }
53
52 private Platform Platform { get; set; } 54 private Platform Platform { get; set; }
53 55
54 private CompressionLevel? DefaultCompressionLevel { get; set; } 56 private CompressionLevel? DefaultCompressionLevel { get; set; }
@@ -79,6 +81,8 @@ namespace WixToolset.Core.CommandLine
79 81
80 var inputsOutputs = this.commandLine.CalculateInputsAndOutputs(creator); 82 var inputsOutputs = this.commandLine.CalculateInputsAndOutputs(creator);
81 83
84 this.OutputPath = inputsOutputs.OutputPath;
85
82 if (this.Messaging.EncounteredError) 86 if (this.Messaging.EncounteredError)
83 { 87 {
84 return Task.FromResult(this.Messaging.LastErrorNumber); 88 return Task.FromResult(this.Messaging.LastErrorNumber);
@@ -117,7 +121,9 @@ namespace WixToolset.Core.CommandLine
117 if (String.IsNullOrEmpty(outputExtension) || ".wix" == outputExtension) 121 if (String.IsNullOrEmpty(outputExtension) || ".wix" == outputExtension)
118 { 122 {
119 var entrySectionType = wixipl.Sections.Single().Type; 123 var entrySectionType = wixipl.Sections.Single().Type;
124
120 inputsOutputs.OutputPath = Path.ChangeExtension(inputsOutputs.OutputPath, DefaultExtensionForSectionType(entrySectionType)); 125 inputsOutputs.OutputPath = Path.ChangeExtension(inputsOutputs.OutputPath, DefaultExtensionForSectionType(entrySectionType));
126 this.OutputPath = inputsOutputs.OutputPath;
121 } 127 }
122 128
123 if (inputsOutputs.OutputType == OutputType.IntermediatePostLink) 129 if (inputsOutputs.OutputType == OutputType.IntermediatePostLink)
@@ -158,6 +164,8 @@ namespace WixToolset.Core.CommandLine
158 164
159 var context = this.ServiceProvider.GetService<ICompileContext>(); 165 var context = this.ServiceProvider.GetService<ICompileContext>();
160 context.Extensions = this.ExtensionManager.GetServices<ICompilerExtension>(); 166 context.Extensions = this.ExtensionManager.GetServices<ICompilerExtension>();
167 context.IntermediateFolder = this.IntermediateFolder;
168 context.OutputPath = this.OutputPath;
161 context.Platform = this.Platform; 169 context.Platform = this.Platform;
162 context.Source = document; 170 context.Source = document;
163 context.CancellationToken = cancellationToken; 171 context.CancellationToken = cancellationToken;
@@ -198,7 +206,9 @@ namespace WixToolset.Core.CommandLine
198 context.BindPaths = bindPaths; 206 context.BindPaths = bindPaths;
199 context.Extensions = this.ExtensionManager.GetServices<ILibrarianExtension>(); 207 context.Extensions = this.ExtensionManager.GetServices<ILibrarianExtension>();
200 context.Localizations = localizations; 208 context.Localizations = localizations;
209 context.IntermediateFolder = this.IntermediateFolder;
201 context.Intermediates = intermediates.Concat(libraries).ToList(); 210 context.Intermediates = intermediates.Concat(libraries).ToList();
211 context.OutputPath = this.OutputPath;
202 context.CancellationToken = cancellationToken; 212 context.CancellationToken = cancellationToken;
203 213
204 try 214 try
@@ -210,7 +220,7 @@ namespace WixToolset.Core.CommandLine
210 { 220 {
211 result.Library.Save(outputPath); 221 result.Library.Save(outputPath);
212 222
213 this.LayoutFiles(this.IntermediateFolder, result.TrackedFiles, null, cancellationToken); 223 this.LayoutFiles(result.TrackedFiles, null, cancellationToken);
214 } 224 }
215 } 225 }
216 catch (WixException e) 226 catch (WixException e)
@@ -232,7 +242,9 @@ namespace WixToolset.Core.CommandLine
232 context.Extensions = this.ExtensionManager.GetServices<ILinkerExtension>(); 242 context.Extensions = this.ExtensionManager.GetServices<ILinkerExtension>();
233 context.ExtensionData = this.ExtensionManager.GetServices<IExtensionData>(); 243 context.ExtensionData = this.ExtensionManager.GetServices<IExtensionData>();
234 context.ExpectedOutputType = inputsOutputs.OutputType; 244 context.ExpectedOutputType = inputsOutputs.OutputType;
245 context.IntermediateFolder = this.IntermediateFolder;
235 context.Intermediates = intermediates.Concat(libraries).ToList(); 246 context.Intermediates = intermediates.Concat(libraries).ToList();
247 context.OutputPath = this.OutputPath;
236 context.SymbolDefinitionCreator = creator; 248 context.SymbolDefinitionCreator = creator;
237 context.CancellationToken = cancellationToken; 249 context.CancellationToken = cancellationToken;
238 250
@@ -242,12 +254,6 @@ namespace WixToolset.Core.CommandLine
242 254
243 private void BindPhase(Intermediate output, IReadOnlyCollection<Localization> localizations, IReadOnlyCollection<string> filterCultures, string cabCachePath, IReadOnlyCollection<IBindPath> bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken) 255 private void BindPhase(Intermediate output, IReadOnlyCollection<Localization> localizations, IReadOnlyCollection<string> filterCultures, string cabCachePath, IReadOnlyCollection<IBindPath> bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken)
244 { 256 {
245 var intermediateFolder = this.IntermediateFolder;
246 if (String.IsNullOrEmpty(intermediateFolder))
247 {
248 intermediateFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
249 }
250
251 IResolveResult resolveResult; 257 IResolveResult resolveResult;
252 { 258 {
253 var context = this.ServiceProvider.GetService<IResolveContext>(); 259 var context = this.ServiceProvider.GetService<IResolveContext>();
@@ -255,9 +261,10 @@ namespace WixToolset.Core.CommandLine
255 context.Extensions = this.ExtensionManager.GetServices<IResolverExtension>(); 261 context.Extensions = this.ExtensionManager.GetServices<IResolverExtension>();
256 context.ExtensionData = this.ExtensionManager.GetServices<IExtensionData>(); 262 context.ExtensionData = this.ExtensionManager.GetServices<IExtensionData>();
257 context.FilterCultures = filterCultures; 263 context.FilterCultures = filterCultures;
258 context.IntermediateFolder = intermediateFolder; 264 context.IntermediateFolder = this.IntermediateFolder;
259 context.IntermediateRepresentation = output; 265 context.IntermediateRepresentation = output;
260 context.Localizations = localizations; 266 context.Localizations = localizations;
267 context.OutputPath = inputsOutputs.OutputPath;
261 context.CancellationToken = cancellationToken; 268 context.CancellationToken = cancellationToken;
262 269
263 var resolver = this.ServiceProvider.GetService<IResolver>(); 270 var resolver = this.ServiceProvider.GetService<IResolver>();
@@ -284,9 +291,9 @@ namespace WixToolset.Core.CommandLine
284 context.ExpectedEmbeddedFiles = resolveResult.ExpectedEmbeddedFiles; 291 context.ExpectedEmbeddedFiles = resolveResult.ExpectedEmbeddedFiles;
285 context.Extensions = this.ExtensionManager.GetServices<IBinderExtension>(); 292 context.Extensions = this.ExtensionManager.GetServices<IBinderExtension>();
286 context.FileSystemExtensions = this.ExtensionManager.GetServices<IFileSystemExtension>(); 293 context.FileSystemExtensions = this.ExtensionManager.GetServices<IFileSystemExtension>();
287 context.IntermediateFolder = intermediateFolder; 294 context.IntermediateFolder = this.IntermediateFolder;
288 context.IntermediateRepresentation = resolveResult.IntermediateRepresentation; 295 context.IntermediateRepresentation = resolveResult.IntermediateRepresentation;
289 context.OutputPath = inputsOutputs.OutputPath; 296 context.OutputPath = this.OutputPath;
290 context.PdbType = inputsOutputs.PdbType; 297 context.PdbType = inputsOutputs.PdbType;
291 context.PdbPath = inputsOutputs.PdbPath; 298 context.PdbPath = inputsOutputs.PdbPath;
292 context.CancellationToken = cancellationToken; 299 context.CancellationToken = cancellationToken;
@@ -300,7 +307,7 @@ namespace WixToolset.Core.CommandLine
300 return; 307 return;
301 } 308 }
302 309
303 this.LayoutFiles(intermediateFolder, bindResult.TrackedFiles, bindResult.FileTransfers, cancellationToken); 310 this.LayoutFiles(bindResult.TrackedFiles, bindResult.FileTransfers, cancellationToken);
304 } 311 }
305 finally 312 finally
306 { 313 {
@@ -308,13 +315,14 @@ namespace WixToolset.Core.CommandLine
308 } 315 }
309 } 316 }
310 317
311 private void LayoutFiles(string intermediateFolder, IReadOnlyCollection<ITrackedFile> trackedFiles, IReadOnlyCollection<IFileTransfer> fileTransfers, CancellationToken cancellationToken) 318 private void LayoutFiles(IReadOnlyCollection<ITrackedFile> trackedFiles, IReadOnlyCollection<IFileTransfer> fileTransfers, CancellationToken cancellationToken)
312 { 319 {
313 var context = this.ServiceProvider.GetService<ILayoutContext>(); 320 var context = this.ServiceProvider.GetService<ILayoutContext>();
314 context.Extensions = this.ExtensionManager.GetServices<ILayoutExtension>(); 321 context.Extensions = this.ExtensionManager.GetServices<ILayoutExtension>();
315 context.TrackedFiles = trackedFiles; 322 context.TrackedFiles = trackedFiles;
316 context.FileTransfers = fileTransfers; 323 context.FileTransfers = fileTransfers;
317 context.IntermediateFolder = intermediateFolder; 324 context.IntermediateFolder = this.IntermediateFolder;
325 context.OutputPath = this.OutputPath;
318 context.TrackingFile = this.TrackingFile; 326 context.TrackingFile = this.TrackingFile;
319 context.ResetAcls = this.commandLine.ResetAcls; 327 context.ResetAcls = this.commandLine.ResetAcls;
320 context.CancellationToken = cancellationToken; 328 context.CancellationToken = cancellationToken;
@@ -368,6 +376,8 @@ namespace WixToolset.Core.CommandLine
368 context.Extensions = this.ExtensionManager.GetServices<IPreprocessorExtension>(); 376 context.Extensions = this.ExtensionManager.GetServices<IPreprocessorExtension>();
369 context.Platform = this.Platform; 377 context.Platform = this.Platform;
370 context.IncludeSearchPaths = includeSearchPaths; 378 context.IncludeSearchPaths = includeSearchPaths;
379 context.IntermediateFolder = this.IntermediateFolder;
380 context.OutputPath = this.OutputPath;
371 context.SourcePath = sourcePath; 381 context.SourcePath = sourcePath;
372 context.Variables = preprocessorVariables; 382 context.Variables = preprocessorVariables;
373 context.CancellationToken = cancellationToken; 383 context.CancellationToken = cancellationToken;
@@ -614,7 +624,14 @@ namespace WixToolset.Core.CommandLine
614 624
615 public string CalculateIntermedateFolder() 625 public string CalculateIntermedateFolder()
616 { 626 {
617 return String.IsNullOrEmpty(this.IntermediateFolder) ? Path.GetTempPath() : this.IntermediateFolder; 627 var intermediateFolder = this.IntermediateFolder;
628
629 if (String.IsNullOrEmpty(intermediateFolder))
630 {
631 intermediateFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
632 }
633
634 return intermediateFolder;
618 } 635 }
619 636
620 public OutputType CalculateOutputType() 637 public OutputType CalculateOutputType()
diff --git a/src/wix/WixToolset.Core/CompileContext.cs b/src/wix/WixToolset.Core/CompileContext.cs
index d84d7aac..f0c99a51 100644
--- a/src/wix/WixToolset.Core/CompileContext.cs
+++ b/src/wix/WixToolset.Core/CompileContext.cs
@@ -23,6 +23,10 @@ namespace WixToolset.Core
23 23
24 public IReadOnlyCollection<ICompilerExtension> Extensions { get; set; } 24 public IReadOnlyCollection<ICompilerExtension> Extensions { get; set; }
25 25
26 public string IntermediateFolder { get; set; }
27
28 public string OutputPath { get; set; }
29
26 public Platform Platform { get; set; } 30 public Platform Platform { get; set; }
27 31
28 public bool IsCurrentPlatform64Bit => this.Platform == Platform.ARM64 || this.Platform == Platform.X64; 32 public bool IsCurrentPlatform64Bit => this.Platform == Platform.ARM64 || this.Platform == Platform.X64;
diff --git a/src/wix/WixToolset.Core/LayoutContext.cs b/src/wix/WixToolset.Core/LayoutContext.cs
index 3def3006..a5a8ea28 100644
--- a/src/wix/WixToolset.Core/LayoutContext.cs
+++ b/src/wix/WixToolset.Core/LayoutContext.cs
@@ -31,6 +31,8 @@ namespace WixToolset.Core
31 31
32 public bool ResetAcls { get; set; } 32 public bool ResetAcls { get; set; }
33 33
34 public string OutputPath { get; set; }
35
34 public CancellationToken CancellationToken { get; set; } 36 public CancellationToken CancellationToken { get; set; }
35 } 37 }
36} 38}
diff --git a/src/wix/WixToolset.Core/LibraryContext.cs b/src/wix/WixToolset.Core/LibraryContext.cs
index e701cadf..a463844e 100644
--- a/src/wix/WixToolset.Core/LibraryContext.cs
+++ b/src/wix/WixToolset.Core/LibraryContext.cs
@@ -31,8 +31,12 @@ namespace WixToolset.Core
31 31
32 public IReadOnlyCollection<Localization> Localizations { get; set; } 32 public IReadOnlyCollection<Localization> Localizations { get; set; }
33 33
34 public string IntermediateFolder { get; set; }
35
34 public IReadOnlyCollection<Intermediate> Intermediates { get; set; } 36 public IReadOnlyCollection<Intermediate> Intermediates { get; set; }
35 37
38 public string OutputPath { get; set; }
39
36 public CancellationToken CancellationToken { get; set; } 40 public CancellationToken CancellationToken { get; set; }
37 } 41 }
38} 42}
diff --git a/src/wix/WixToolset.Core/LinkContext.cs b/src/wix/WixToolset.Core/LinkContext.cs
index b99bb9c4..10223171 100644
--- a/src/wix/WixToolset.Core/LinkContext.cs
+++ b/src/wix/WixToolset.Core/LinkContext.cs
@@ -24,8 +24,12 @@ namespace WixToolset.Core
24 24
25 public OutputType ExpectedOutputType { get; set; } 25 public OutputType ExpectedOutputType { get; set; }
26 26
27 public string IntermediateFolder { get; set; }
28
27 public IReadOnlyCollection<Intermediate> Intermediates { get; set; } 29 public IReadOnlyCollection<Intermediate> Intermediates { get; set; }
28 30
31 public string OutputPath { get; set; }
32
29 public ISymbolDefinitionCreator SymbolDefinitionCreator { get; set; } 33 public ISymbolDefinitionCreator SymbolDefinitionCreator { get; set; }
30 34
31 public CancellationToken CancellationToken { get; set; } 35 public CancellationToken CancellationToken { get; set; }
diff --git a/src/wix/WixToolset.Core/PreprocessContext.cs b/src/wix/WixToolset.Core/PreprocessContext.cs
index 986045ff..1b31e150 100644
--- a/src/wix/WixToolset.Core/PreprocessContext.cs
+++ b/src/wix/WixToolset.Core/PreprocessContext.cs
@@ -24,6 +24,10 @@ namespace WixToolset.Core
24 24
25 public IReadOnlyCollection<string> IncludeSearchPaths { get; set; } 25 public IReadOnlyCollection<string> IncludeSearchPaths { get; set; }
26 26
27 public string IntermediateFolder { get; set; }
28
29 public string OutputPath { get; set; }
30
27 public string SourcePath { get; set; } 31 public string SourcePath { get; set; }
28 32
29 public IDictionary<string, string> Variables { get; set; } 33 public IDictionary<string, string> Variables { get; set; }
diff --git a/src/wix/WixToolset.Core/ResolveContext.cs b/src/wix/WixToolset.Core/ResolveContext.cs
index 638c8079..a56ce4c9 100644
--- a/src/wix/WixToolset.Core/ResolveContext.cs
+++ b/src/wix/WixToolset.Core/ResolveContext.cs
@@ -37,6 +37,8 @@ namespace WixToolset.Core
37 37
38 public bool AllowUnresolvedVariables { get; set; } 38 public bool AllowUnresolvedVariables { get; set; }
39 39
40 public string OutputPath { get; set; }
41
40 public CancellationToken CancellationToken { get; set; } 42 public CancellationToken CancellationToken { get; set; }
41 } 43 }
42} 44}
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/LinkerFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/LinkerFixture.cs
index 2b3adfb4..c3f16722 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/LinkerFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/LinkerFixture.cs
@@ -32,7 +32,9 @@ namespace WixToolsetTest.CoreIntegration
32 var context = serviceProvider.GetService<ILinkContext>(); 32 var context = serviceProvider.GetService<ILinkContext>();
33 context.Extensions = Array.Empty<WixToolset.Extensibility.ILinkerExtension>(); 33 context.Extensions = Array.Empty<WixToolset.Extensibility.ILinkerExtension>();
34 context.ExtensionData = Array.Empty<WixToolset.Extensibility.IExtensionData>(); 34 context.ExtensionData = Array.Empty<WixToolset.Extensibility.IExtensionData>();
35 context.IntermediateFolder = Path.GetTempPath();
35 context.Intermediates = new[] { intermediate1, intermediate2 }; 36 context.Intermediates = new[] { intermediate1, intermediate2 };
37 context.OutputPath = Path.Combine(context.IntermediateFolder, "test.msi");
36 context.SymbolDefinitionCreator = creator; 38 context.SymbolDefinitionCreator = creator;
37 39
38 var linker = serviceProvider.GetService<ILinker>(); 40 var linker = serviceProvider.GetService<ILinker>();