From 39c7e2bb0399802e65a3025c4a73db211e730479 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sun, 1 Oct 2017 14:25:33 -0700 Subject: Add support for BindPaths and building .wixlibs --- src/WixToolset.Core/CommandLine/BuildCommand.cs | 196 +++++++++++++++++++++--- 1 file changed, 171 insertions(+), 25 deletions(-) (limited to 'src/WixToolset.Core/CommandLine/BuildCommand.cs') 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 using System.IO; using System.Linq; using WixToolset.Data; + using WixToolset.Extensibility; internal class BuildCommand : ICommand { - public BuildCommand(IEnumerable sources, IDictionary preprocessorVariables, IEnumerable locFiles, string outputPath, IEnumerable cultures, string contentsFile, string outputsFile, string builtOutputsFile, string wixProjectFile) + public BuildCommand(IEnumerable sources, IDictionary preprocessorVariables, IEnumerable locFiles, IEnumerable libraryFiles, string outputPath, OutputType outputType, IEnumerable cultures, bool bindFiles, IEnumerable bindPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile, string wixProjectFile) { this.LocFiles = locFiles; + this.LibraryFiles = libraryFiles; this.PreprocessorVariables = preprocessorVariables; this.SourceFiles = sources; this.OutputPath = outputPath; + this.OutputType = outputType; this.Cultures = cultures; + this.BindFiles = bindFiles; + this.BindPaths = bindPaths; + + this.IntermediateFolder = intermediateFolder ?? Path.GetTempPath(); this.ContentsFile = contentsFile; this.OutputsFile = outputsFile; this.BuiltOutputsFile = builtOutputsFile; @@ -26,14 +33,24 @@ namespace WixToolset.Core public IEnumerable LocFiles { get; } + public IEnumerable LibraryFiles { get; } + private IEnumerable SourceFiles { get; } private IDictionary PreprocessorVariables { get; } private string OutputPath { get; } + private OutputType OutputType { get; } + public IEnumerable Cultures { get; } + public bool BindFiles { get; } + + public IEnumerable BindPaths { get; } + + public string IntermediateFolder { get; } + public string ContentsFile { get; } public string OutputsFile { get; } @@ -44,21 +61,135 @@ namespace WixToolset.Core public int Execute() { - var intermediates = CompilePhase(); + var intermediates = this.CompilePhase(); + + var tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions()); + + if (this.OutputType == OutputType.Library) + { + this.LibraryPhase(intermediates, tableDefinitions); + } + else + { + var output = this.LinkPhase(intermediates, tableDefinitions); + + if (!Messaging.Instance.EncounteredError) + { + this.BindPhase(output, tableDefinitions); + } + } + + return Messaging.Instance.LastErrorNumber; + } + + private IEnumerable CompilePhase() + { + var intermediates = new List(); + + var preprocessor = new Preprocessor(); + + var compiler = new Compiler(); + + foreach (var sourceFile in this.SourceFiles) + { + var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables); + + var intermediate = compiler.Compile(document); + + intermediates.Add(intermediate); + } + + return intermediates; + } + + private void LibraryPhase(IEnumerable intermediates, TableDefinitionCollection tableDefinitions) + { + var localizations = this.LoadLocalizationFiles(tableDefinitions).ToList(); + + // If there was an error adding localization files, then bail. + if (Messaging.Instance.EncounteredError) + { + return; + } var sections = intermediates.SelectMany(i => i.Sections).ToList(); + LibraryBinaryFileResolver resolver = null; + + if (this.BindFiles) + { + resolver = new LibraryBinaryFileResolver(); + resolver.FileManagers = new List { new BinderFileManager() }; ; + resolver.VariableResolver = new WixVariableResolver(); + + BinderFileManagerCore core = new BinderFileManagerCore(); + core.AddBindPaths(this.BindPaths, BindStage.Normal); + + foreach (var fileManager in resolver.FileManagers) + { + fileManager.Core = core; + } + } + + var librarian = new Librarian(); + + var library = librarian.Combine(sections, localizations, resolver); + + library?.Save(this.OutputPath); + } + + private Output LinkPhase(IEnumerable intermediates, TableDefinitionCollection tableDefinitions) + { + var sections = intermediates.SelectMany(i => i.Sections).ToList(); + + sections.AddRange(SectionsFromLibraries(tableDefinitions)); + var linker = new Linker(); - var output = linker.Link(sections, OutputType.Product); + var output = linker.Link(sections, this.OutputType); + + return output; + } + + private IEnumerable
SectionsFromLibraries(TableDefinitionCollection tableDefinitions) + { + var sections = new List
(); + + if (this.LibraryFiles != null) + { + foreach (var libraryFile in this.LibraryFiles) + { + try + { + var library = Library.Load(libraryFile, tableDefinitions, false); + + sections.AddRange(library.Sections); + } + catch (WixCorruptFileException e) + { + Messaging.Instance.OnMessage(e.Error); + } + catch (WixUnexpectedFileFormatException e) + { + Messaging.Instance.OnMessage(e.Error); + } + } + } - var localizer = new Localizer(); + return sections; + } + + private void BindPhase(Output output, TableDefinitionCollection tableDefinitions) + { + var localizations = this.LoadLocalizationFiles(tableDefinitions).ToList(); + + var localizer = new Localizer(localizations); + + var resolver = new WixVariableResolver(localizer); var binder = new Binder(); - binder.TempFilesLocation = Path.GetTempPath(); - binder.WixVariableResolver = new WixVariableResolver(); - binder.WixVariableResolver.Localizer = localizer; - binder.AddExtension(new BinderFileManager()); + binder.TempFilesLocation = this.IntermediateFolder; + binder.WixVariableResolver = resolver; binder.SuppressValidation = true; binder.ContentsFile = this.ContentsFile; @@ -66,35 +197,50 @@ namespace WixToolset.Core binder.BuiltOutputsFile = this.BuiltOutputsFile; binder.WixprojectFile = this.WixProjectFile; - foreach (var loc in this.LocFiles) + if (this.BindPaths != null) { - var localization = Localizer.ParseLocalizationFile(loc, linker.TableDefinitions); - binder.WixVariableResolver.Localizer.AddLocalization(localization); + binder.BindPaths.AddRange(this.BindPaths); } - binder.Bind(output, this.OutputPath); + binder.AddExtension(new BinderFileManager()); - return 0; + binder.Bind(output, this.OutputPath); } - private IEnumerable CompilePhase() + private IEnumerable LoadLocalizationFiles(TableDefinitionCollection tableDefinitions) { - var intermediates = new List(); - - var preprocessor = new Preprocessor(); + foreach (var loc in this.LocFiles) + { + var localization = Localizer.ParseLocalizationFile(loc, tableDefinitions); - var compiler = new Compiler(); + yield return localization; + } + } - foreach (var sourceFile in this.SourceFiles) - { - var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables); + /// + /// File resolution mechanism to create binary library. + /// + private class LibraryBinaryFileResolver : ILibraryBinaryFileResolver + { + public IEnumerable FileManagers { get; set; } - var intermediate = compiler.Compile(document); + public WixVariableResolver VariableResolver { get; set; } - intermediates.Add(intermediate); + public string Resolve(SourceLineNumber sourceLineNumber, string table, string path) + { + string resolvedPath = this.VariableResolver.ResolveVariables(sourceLineNumber, path, false); + + foreach (IBinderFileManager fileManager in this.FileManagers) + { + string finalPath = fileManager.ResolveFile(resolvedPath, table, sourceLineNumber, BindStage.Normal); + if (!String.IsNullOrEmpty(finalPath)) + { + return finalPath; + } + } + + return null; } - - return intermediates; } } } -- cgit v1.2.3-55-g6feb