aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/CommandLine/BuildCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/CommandLine/BuildCommand.cs')
-rw-r--r--src/WixToolset.Core/CommandLine/BuildCommand.cs196
1 files changed, 171 insertions, 25 deletions
diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs
index ffb48305..d8954cb7 100644
--- a/src/WixToolset.Core/CommandLine/BuildCommand.cs
+++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs
@@ -7,17 +7,24 @@ namespace WixToolset.Core
7 using System.IO; 7 using System.IO;
8 using System.Linq; 8 using System.Linq;
9 using WixToolset.Data; 9 using WixToolset.Data;
10 using WixToolset.Extensibility;
10 11
11 internal class BuildCommand : ICommand 12 internal class BuildCommand : ICommand
12 { 13 {
13 public BuildCommand(IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables, IEnumerable<string> locFiles, string outputPath, IEnumerable<string> cultures, string contentsFile, string outputsFile, string builtOutputsFile, string wixProjectFile) 14 public BuildCommand(IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables, IEnumerable<string> locFiles, IEnumerable<string> libraryFiles, string outputPath, OutputType outputType, IEnumerable<string> cultures, bool bindFiles, IEnumerable<BindPath> bindPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile, string wixProjectFile)
14 { 15 {
15 this.LocFiles = locFiles; 16 this.LocFiles = locFiles;
17 this.LibraryFiles = libraryFiles;
16 this.PreprocessorVariables = preprocessorVariables; 18 this.PreprocessorVariables = preprocessorVariables;
17 this.SourceFiles = sources; 19 this.SourceFiles = sources;
18 this.OutputPath = outputPath; 20 this.OutputPath = outputPath;
21 this.OutputType = outputType;
19 22
20 this.Cultures = cultures; 23 this.Cultures = cultures;
24 this.BindFiles = bindFiles;
25 this.BindPaths = bindPaths;
26
27 this.IntermediateFolder = intermediateFolder ?? Path.GetTempPath();
21 this.ContentsFile = contentsFile; 28 this.ContentsFile = contentsFile;
22 this.OutputsFile = outputsFile; 29 this.OutputsFile = outputsFile;
23 this.BuiltOutputsFile = builtOutputsFile; 30 this.BuiltOutputsFile = builtOutputsFile;
@@ -26,14 +33,24 @@ namespace WixToolset.Core
26 33
27 public IEnumerable<string> LocFiles { get; } 34 public IEnumerable<string> LocFiles { get; }
28 35
36 public IEnumerable<string> LibraryFiles { get; }
37
29 private IEnumerable<SourceFile> SourceFiles { get; } 38 private IEnumerable<SourceFile> SourceFiles { get; }
30 39
31 private IDictionary<string, string> PreprocessorVariables { get; } 40 private IDictionary<string, string> PreprocessorVariables { get; }
32 41
33 private string OutputPath { get; } 42 private string OutputPath { get; }
34 43
44 private OutputType OutputType { get; }
45
35 public IEnumerable<string> Cultures { get; } 46 public IEnumerable<string> Cultures { get; }
36 47
48 public bool BindFiles { get; }
49
50 public IEnumerable<BindPath> BindPaths { get; }
51
52 public string IntermediateFolder { get; }
53
37 public string ContentsFile { get; } 54 public string ContentsFile { get; }
38 55
39 public string OutputsFile { get; } 56 public string OutputsFile { get; }
@@ -44,21 +61,135 @@ namespace WixToolset.Core
44 61
45 public int Execute() 62 public int Execute()
46 { 63 {
47 var intermediates = CompilePhase(); 64 var intermediates = this.CompilePhase();
65
66 var tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
67
68 if (this.OutputType == OutputType.Library)
69 {
70 this.LibraryPhase(intermediates, tableDefinitions);
71 }
72 else
73 {
74 var output = this.LinkPhase(intermediates, tableDefinitions);
75
76 if (!Messaging.Instance.EncounteredError)
77 {
78 this.BindPhase(output, tableDefinitions);
79 }
80 }
81
82 return Messaging.Instance.LastErrorNumber;
83 }
84
85 private IEnumerable<Intermediate> CompilePhase()
86 {
87 var intermediates = new List<Intermediate>();
88
89 var preprocessor = new Preprocessor();
90
91 var compiler = new Compiler();
92
93 foreach (var sourceFile in this.SourceFiles)
94 {
95 var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables);
96
97 var intermediate = compiler.Compile(document);
98
99 intermediates.Add(intermediate);
100 }
101
102 return intermediates;
103 }
104
105 private void LibraryPhase(IEnumerable<Intermediate> intermediates, TableDefinitionCollection tableDefinitions)
106 {
107 var localizations = this.LoadLocalizationFiles(tableDefinitions).ToList();
108
109 // If there was an error adding localization files, then bail.
110 if (Messaging.Instance.EncounteredError)
111 {
112 return;
113 }
48 114
49 var sections = intermediates.SelectMany(i => i.Sections).ToList(); 115 var sections = intermediates.SelectMany(i => i.Sections).ToList();
50 116
117 LibraryBinaryFileResolver resolver = null;
118
119 if (this.BindFiles)
120 {
121 resolver = new LibraryBinaryFileResolver();
122 resolver.FileManagers = new List<IBinderFileManager> { new BinderFileManager() }; ;
123 resolver.VariableResolver = new WixVariableResolver();
124
125 BinderFileManagerCore core = new BinderFileManagerCore();
126 core.AddBindPaths(this.BindPaths, BindStage.Normal);
127
128 foreach (var fileManager in resolver.FileManagers)
129 {
130 fileManager.Core = core;
131 }
132 }
133
134 var librarian = new Librarian();
135
136 var library = librarian.Combine(sections, localizations, resolver);
137
138 library?.Save(this.OutputPath);
139 }
140
141 private Output LinkPhase(IEnumerable<Intermediate> intermediates, TableDefinitionCollection tableDefinitions)
142 {
143 var sections = intermediates.SelectMany(i => i.Sections).ToList();
144
145 sections.AddRange(SectionsFromLibraries(tableDefinitions));
146
51 var linker = new Linker(); 147 var linker = new Linker();
52 148
53 var output = linker.Link(sections, OutputType.Product); 149 var output = linker.Link(sections, this.OutputType);
150
151 return output;
152 }
153
154 private IEnumerable<Section> SectionsFromLibraries(TableDefinitionCollection tableDefinitions)
155 {
156 var sections = new List<Section>();
157
158 if (this.LibraryFiles != null)
159 {
160 foreach (var libraryFile in this.LibraryFiles)
161 {
162 try
163 {
164 var library = Library.Load(libraryFile, tableDefinitions, false);
165
166 sections.AddRange(library.Sections);
167 }
168 catch (WixCorruptFileException e)
169 {
170 Messaging.Instance.OnMessage(e.Error);
171 }
172 catch (WixUnexpectedFileFormatException e)
173 {
174 Messaging.Instance.OnMessage(e.Error);
175 }
176 }
177 }
54 178
55 var localizer = new Localizer(); 179 return sections;
180 }
181
182 private void BindPhase(Output output, TableDefinitionCollection tableDefinitions)
183 {
184 var localizations = this.LoadLocalizationFiles(tableDefinitions).ToList();
185
186 var localizer = new Localizer(localizations);
187
188 var resolver = new WixVariableResolver(localizer);
56 189
57 var binder = new Binder(); 190 var binder = new Binder();
58 binder.TempFilesLocation = Path.GetTempPath(); 191 binder.TempFilesLocation = this.IntermediateFolder;
59 binder.WixVariableResolver = new WixVariableResolver(); 192 binder.WixVariableResolver = resolver;
60 binder.WixVariableResolver.Localizer = localizer;
61 binder.AddExtension(new BinderFileManager());
62 binder.SuppressValidation = true; 193 binder.SuppressValidation = true;
63 194
64 binder.ContentsFile = this.ContentsFile; 195 binder.ContentsFile = this.ContentsFile;
@@ -66,35 +197,50 @@ namespace WixToolset.Core
66 binder.BuiltOutputsFile = this.BuiltOutputsFile; 197 binder.BuiltOutputsFile = this.BuiltOutputsFile;
67 binder.WixprojectFile = this.WixProjectFile; 198 binder.WixprojectFile = this.WixProjectFile;
68 199
69 foreach (var loc in this.LocFiles) 200 if (this.BindPaths != null)
70 { 201 {
71 var localization = Localizer.ParseLocalizationFile(loc, linker.TableDefinitions); 202 binder.BindPaths.AddRange(this.BindPaths);
72 binder.WixVariableResolver.Localizer.AddLocalization(localization);
73 } 203 }
74 204
75 binder.Bind(output, this.OutputPath); 205 binder.AddExtension(new BinderFileManager());
76 206
77 return 0; 207 binder.Bind(output, this.OutputPath);
78 } 208 }
79 209
80 private IEnumerable<Intermediate> CompilePhase() 210 private IEnumerable<Localization> LoadLocalizationFiles(TableDefinitionCollection tableDefinitions)
81 { 211 {
82 var intermediates = new List<Intermediate>(); 212 foreach (var loc in this.LocFiles)
83 213 {
84 var preprocessor = new Preprocessor(); 214 var localization = Localizer.ParseLocalizationFile(loc, tableDefinitions);
85 215
86 var compiler = new Compiler(); 216 yield return localization;
217 }
218 }
87 219
88 foreach (var sourceFile in this.SourceFiles) 220 /// <summary>
89 { 221 /// File resolution mechanism to create binary library.
90 var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables); 222 /// </summary>
223 private class LibraryBinaryFileResolver : ILibraryBinaryFileResolver
224 {
225 public IEnumerable<IBinderFileManager> FileManagers { get; set; }
91 226
92 var intermediate = compiler.Compile(document); 227 public WixVariableResolver VariableResolver { get; set; }
93 228
94 intermediates.Add(intermediate); 229 public string Resolve(SourceLineNumber sourceLineNumber, string table, string path)
230 {
231 string resolvedPath = this.VariableResolver.ResolveVariables(sourceLineNumber, path, false);
232
233 foreach (IBinderFileManager fileManager in this.FileManagers)
234 {
235 string finalPath = fileManager.ResolveFile(resolvedPath, table, sourceLineNumber, BindStage.Normal);
236 if (!String.IsNullOrEmpty(finalPath))
237 {
238 return finalPath;
239 }
240 }
241
242 return null;
95 } 243 }
96
97 return intermediates;
98 } 244 }
99 } 245 }
100} 246}