ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { var sourcePath = sender.SourcePath; if (null == sender.Reference) { // the main file is not copied anywhere, as we copy required files around it where VS wrote the main file // this is managed by the Collation class, querying the build mode for where publishing is relative to // ignore any subdirectory on this module return; } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); if (sender.SourceModule != null && sender.SourceModule.MetaData != null) { var destinationPath = sender.Macros["CopyDir"].Parse(); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("IF NOT EXIST {0} MKDIR {0}", destinationPath)); commands.Add(System.String.Format(@"{0} {1} $(OutputPath)$(TargetFileName) {2} {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), destinationPath, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); var project = sender.SourceModule.MetaData as VSSolutionBuilder.VSProject; var config = project.GetConfiguration(sender.SourceModule); config.AddPostBuildCommands(commands); } else { var commands = new Bam.Core.StringArray(); if (sender is CollatedDirectory) { // Windows XCOPY requires the directory name to be added to the destination, while Posix cp does not commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir){3}\ {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), sender.CreateTokenizedString("$(0)/@ifnotempty($(CopiedFilename),$(CopiedFilename),@filename($(1)))", sender.SubDirectory, sourcePath).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir){3}\ {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), sender.SubDirectory, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } var project = sender.Reference.SourceModule.MetaData as VSSolutionBuilder.VSProject; var config = project.GetConfiguration(sender.Reference.SourceModule); config.AddPostBuildCommands(commands); } }
IInstallNameToolPolicy.InstallName( InstallNameModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString oldName, Bam.Core.TokenizedString newName) { var originalModule = sender.Source.SourceModule; if (originalModule == null) { return; } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); var commands = new Bam.Core.StringArray(); if (sender.Source.SourceModule != null && sender.Source.SourceModule.MetaData != null) { commands.Add(System.String.Format("{0} {1} {2} {3} {4} {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), oldName.Parse(), newName.Parse(), sender.Source.GeneratedPaths[CollatedObject.Key].Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); var target = sender.Source.SourceModule.MetaData as XcodeBuilder.Target; var configuration = target.GetConfiguration(sender.Source.SourceModule); target.AddPostBuildCommands(commands, configuration); } else { var destinationFolder = "$CONFIGURATION_BUILD_DIR"; if (sender.Source.Reference != null) { destinationFolder = "$CONFIGURATION_BUILD_DIR/$EXECUTABLE_FOLDER_PATH"; } commands.Add(System.String.Format("{0} {1} {2} {3} {4}/{5} {6}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), oldName.Parse(), newName.Parse(), destinationFolder, sender.Source.CreateTokenizedString("$(0)/@filename($(1))", sender.Source.SubDirectory, sender.Source.SourcePath).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); var target = sender.Source.Reference.SourceModule.MetaData as XcodeBuilder.Target; var configuration = target.GetConfiguration(sender.Source.Reference.SourceModule); target.AddPostBuildCommands(commands, configuration); } }
IAssemblerPolicy.Assemble( AssembledObjectFile sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString objectFilePath, Bam.Core.Module source) { var encapsulating = sender.GetEncapsulatingReferencedModule(); var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution; var project = solution.EnsureProjectExists(encapsulating); var config = project.GetConfiguration(encapsulating); var output = objectFilePath.Parse(); var args = new Bam.Core.StringArray(); args.Add(CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add("%(FullPath)"); var customBuild = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.CustomBuild, include: sender.InputPath, uniqueToProject: true); customBuild.AddSetting("Command", args.ToString(' '), condition: config.ConditionText); customBuild.AddSetting("Message", System.String.Format("Assembling {0}", System.IO.Path.GetFileName(sender.InputPath.Parse())), condition: config.ConditionText); customBuild.AddSetting("Outputs", output, condition: config.ConditionText); sender.MetaData = customBuild; }
Serialize() { var document = new System.Xml.XmlDocument(); var projectEl = this.CreateRootProject(document); projectEl.SetAttribute("ToolsVersion", "4.0"); // TODO: get this number from VisualC var filtersEl = document.CreateVSItemGroup(parentEl: projectEl); foreach (var filter in this.Filters) { var filterEl = document.CreateVSElement("Filter", parentEl: filtersEl); filterEl.SetAttribute("Include", filter.Key); document.CreateVSElement("UniqueIdentifier", new DeterministicGuid("VSFilter" + filter.Key).Guid.ToString("B").ToUpper(), parentEl: filterEl); var filesEl = document.CreateVSItemGroup(parentEl: projectEl); var extensions = new Bam.Core.StringArray(); foreach (var setting in filter.Value) { var path = setting.Include; var extension = System.IO.Path.GetExtension(path.Parse()).TrimStart(new[] { '.' }); extensions.AddUnique(extension); setting.Serialize(document, filesEl); } if (extensions.Count > 0) { document.CreateVSElement("Extensions", extensions.ToString(';'), parentEl: filterEl); } } return(document); }
IArchivingPolicy.Archive( StaticLibrary sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString libraryPath, System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> objectFiles, System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> headers) { var commandLineArgs = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLineArgs); var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(libraryPath); foreach (var input in objectFiles) { rule.AddPrerequisite(input, C.ObjectFile.Key); } var tool = sender.Tool as Bam.Core.ICommandLineTool; var command = new System.Text.StringBuilder(); command.AppendFormat("{0} {1} $^ {2}", CommandLineProcessor.Processor.StringifyTool(tool), commandLineArgs.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(tool)); rule.AddShellCommand(command.ToString()); var libraryFileDir = System.IO.Path.GetDirectoryName(libraryPath.ToString()); meta.CommonMetaData.Directories.AddUnique(libraryFileDir); meta.CommonMetaData.ExtendEnvironmentVariables(tool.EnvironmentVariables); }
ICompilationPolicy.Compile( ObjectFile sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString objectFilePath, Bam.Core.Module source) { var commandLineArgs = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLineArgs); var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(objectFilePath); rule.AddPrerequisite(source, C.SourceFile.Key); var tool = sender.Tool as Bam.Core.ICommandLineTool; var command = new System.Text.StringBuilder(); command.AppendFormat("{0} {1} $< {2}", CommandLineProcessor.Processor.StringifyTool(tool), commandLineArgs.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(tool)); rule.AddShellCommand(command.ToString()); var objectFileDir = System.IO.Path.GetDirectoryName(objectFilePath.ToString()); meta.CommonMetaData.Directories.AddUnique(objectFileDir); meta.CommonMetaData.ExtendEnvironmentVariables(tool.EnvironmentVariables); }
IZipToolPolicy.Zip( ZipModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString zipOutputPath, Bam.Core.TokenizedString zipInputPath) { var encapsulating = sender.GetEncapsulatingReferencedModule(); var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta; var target = workspace.EnsureTargetExists(encapsulating); target.EnsureOutputFileReferenceExists( zipOutputPath, XcodeBuilder.FileReference.EFileType.ZipArchive, XcodeBuilder.Target.EProductType.Utility); var configuration = target.GetConfiguration(encapsulating); configuration.SetProductName(Bam.Core.TokenizedString.CreateVerbatim("PythonZip")); var commands = new Bam.Core.StringArray(); var args = new Bam.Core.StringArray(); args.Add(System.String.Format("cd {0} &&", Bam.Core.IOWrapper.EscapeSpacesInPath(zipInputPath.ToString()))); args.Add(CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add(System.String.Format("{0}", Bam.Core.IOWrapper.EscapeSpacesInPath(zipOutputPath.ToString()))); args.Add("*"); args.Add("|| true"); // because zip returns 12 (nothing to do) upon success args.Add(CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool)); commands.Add(args.ToString(' ')); target.AddPreBuildCommands(commands, configuration); }
IInstallNameToolPolicy.InstallName( InstallNameModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString oldName, Bam.Core.TokenizedString newName) { var originalModule = (sender.Source as ICollatedObject).SourceModule; if (originalModule == null) { return; } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); var commands = new Bam.Core.StringArray(); // TODO: check what happens for prebuilt modules (there shouldn't be any metadata) commands.Add(System.String.Format("{0} {1} {2} {3} {4} {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), oldName.ToString(), newName.ToString(), sender.Source.GeneratedPaths[CollatedObject.Key].ToString(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); var target = originalModule.MetaData as XcodeBuilder.Target; var configuration = target.GetConfiguration(originalModule); target.AddPostBuildCommands(commands, configuration); }
IExternalSourceGeneratorPolicy.GenerateSource( ExternalSourceGenerator sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString executable, Bam.Core.TokenizedStringArray arguments, Bam.Core.TokenizedString output_directory, System.Collections.Generic.IReadOnlyDictionary <string, Bam.Core.TokenizedString> expected_output_files, System.Collections.Generic.IReadOnlyDictionary <string, Bam.Core.TokenizedString> input_files ) { var encapsulating = sender.GetEncapsulatingReferencedModule(); var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution; var project = solution.EnsureProjectExists(encapsulating); var config = project.GetConfiguration(encapsulating); var args = new Bam.Core.StringArray(); args.Add(System.String.Format("{0} {1}", executable.ToStringQuoteIfNecessary(), arguments.ToString(' '))); foreach (var input in input_files.Values) { config.AddOtherFile(input); var customBuild = config.GetSettingsGroup( VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.CustomBuild, include: input, uniqueToProject: true ); customBuild.AddSetting("Command", args.ToString(' '), condition: config.ConditionText); customBuild.AddSetting("Message", System.String.Format("Generating outputs from {0}", input.ToString()), condition: config.ConditionText); customBuild.AddSetting("Outputs", expected_output_files.Values, condition: config.ConditionText); customBuild.AddSetting("AdditionalInputs", input_files.Values, condition: config.ConditionText); } }
IArchivingPolicy.Archive( StaticLibrary sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString libraryPath, System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> objectFiles, System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> headers) { var commandLineArgs = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLineArgs); var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(libraryPath); foreach (var input in objectFiles) { rule.AddPrerequisite(input, C.ObjectFile.Key); } var tool = sender.Tool as Bam.Core.ICommandLineTool; var command = new System.Text.StringBuilder(); command.AppendFormat("{0} {1} $^ {2}", CommandLineProcessor.Processor.StringifyTool(tool), commandLineArgs.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(tool)); rule.AddShellCommand(command.ToString()); var libraryFileDir = System.IO.Path.GetDirectoryName(libraryPath.ToString()); meta.CommonMetaData.Directories.AddUnique(libraryFileDir); meta.CommonMetaData.ExtendEnvironmentVariables(tool.EnvironmentVariables); }
void IMocGenerationPolicy.Moc( MocGeneratedSource sender, Bam.Core.ExecutionContext context, Bam.Core.ICommandLineTool mocCompiler, Bam.Core.TokenizedString generatedMocSource, C.HeaderFile source) { var encapsulating = sender.GetEncapsulatingReferencedModule(); var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta; var target = workspace.EnsureTargetExists(encapsulating); var configuration = target.GetConfiguration(encapsulating); var output = generatedMocSource.Parse(); var sourcePath = source.InputPath.Parse(); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("[[ ! -d {0} ]] && mkdir -p {0}", System.IO.Path.GetDirectoryName(output))); var args = new Bam.Core.StringArray(); args.Add(CommandLineProcessor.Processor.StringifyTool(mocCompiler)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add(System.String.Format("-o {0}", output)); args.Add(sourcePath); var moc_commandLine = args.ToString(' '); commands.Add(System.String.Format("if [[ ! -e {0} || {1} -nt {0} ]]", output, sourcePath)); commands.Add("then"); commands.Add(System.String.Format("\techo {0}", moc_commandLine)); commands.Add(System.String.Format("\t{0}", moc_commandLine)); commands.Add("fi"); target.AddPreBuildCommands(commands, configuration); }
AddSetting( string name, Bam.Core.StringArray value, string condition = null, bool inheritExisting = false) { lock (this.Settings) { if (0 == value.Count) { return; } var linearized = value.ToString(';'); if (this.Settings.Any(item => item.Name == name && item.Condition == condition)) { var settingOption = this.Settings.Where(item => item.Name == name && item.Condition == condition).First(); if (settingOption.Value.Contains(linearized)) { return; } throw new Bam.Core.Exception("Cannot append {3}, to the option {0} as it already exists for condition {1}: {2}", name, condition, this.Settings.Where(item => item.Name == name && item.Condition == condition).First().Value.ToString(), linearized); } this.Settings.AddUnique(new VSSetting(name, inheritExisting ? System.String.Format("{0};%({1})", linearized, name) : linearized, condition)); } }
IObjCopyToolPolicy.ObjCopy( ObjCopyModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString originalPath, Bam.Core.TokenizedString copiedPath) { var mode = (sender.Settings as IObjCopyToolSettings).Mode; // if linking debug data, add to the strip var meta = (EObjCopyToolMode.AddGNUDebugLink == mode) ? sender.SourceModule.MetaData as MakeFileBuilder.MakeFileMeta : new MakeFileBuilder.MakeFileMeta(sender); var rule = (EObjCopyToolMode.AddGNUDebugLink == mode) ? meta.Rules[0] :meta.AddRule(); if (EObjCopyToolMode.AddGNUDebugLink == mode) { rule.AddOrderOnlyDependency(copiedPath.Parse()); } else { meta.CommonMetaData.AddDirectory(sender.CreateTokenizedString("@dir($(0))", copiedPath).Parse()); var sourceFilename = System.IO.Path.GetFileName(originalPath.Parse()); rule.AddTarget(copiedPath, variableName: "objcopy_" + sourceFilename); rule.AddPrerequisite(originalPath); } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); rule.AddShellCommand(System.String.Format("{0} {1} {2}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); }
IAssemblerPolicy.Assemble( AssembledObjectFile sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString objectFilePath, Bam.Core.Module source) { if (!sender.PerformCompilation) { return; } var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(objectFilePath); rule.AddPrerequisite(source, C.SourceFile.Key); var outputPath = objectFilePath.Parse(); var args = new Bam.Core.StringArray(); args.Add(CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add("$<"); rule.AddShellCommand(args.ToString(' ')); meta.CommonMetaData.AddDirectory(System.IO.Path.GetDirectoryName(outputPath)); }
IObjCopyToolPolicy.ObjCopy( ObjCopyModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString originalPath, Bam.Core.TokenizedString copiedPath) { var mode = (sender.Settings as IObjCopyToolSettings).Mode; // if linking debug data, add to the strip var meta = (EObjCopyToolMode.AddGNUDebugLink == mode) ? sender.SourceModule.MetaData as MakeFileBuilder.MakeFileMeta : new MakeFileBuilder.MakeFileMeta(sender); var rule = (EObjCopyToolMode.AddGNUDebugLink == mode) ? meta.Rules[0] :meta.AddRule(); if (EObjCopyToolMode.AddGNUDebugLink == mode) { rule.AddOrderOnlyDependency(copiedPath.Parse()); } else { meta.CommonMetaData.Directories.AddUnique(sender.CreateTokenizedString("@dir($(0))", copiedPath).Parse()); var sourceFilename = System.IO.Path.GetFileName(originalPath.Parse()); rule.AddTarget(copiedPath, variableName: "objcopy_" + sourceFilename); rule.AddPrerequisite(originalPath); } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); rule.AddShellCommand(System.String.Format("{0} {1} {2}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); }
void IRccGenerationPolicy.Rcc( RccGeneratedSource sender, Bam.Core.ExecutionContext context, Bam.Core.ICommandLineTool rccCompiler, Bam.Core.TokenizedString generatedRccSource, QRCFile source) { var encapsulating = sender.GetEncapsulatingReferencedModule(); var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution; var project = solution.EnsureProjectExists(encapsulating); var config = project.GetConfiguration(encapsulating); var output = generatedRccSource.Parse(); var args = new Bam.Core.StringArray(); args.Add(CommandLineProcessor.Processor.StringifyTool(rccCompiler)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add(System.String.Format("-o {0}", output)); args.Add("%(FullPath)"); config.AddOtherFile(source); var customBuild = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.CustomBuild, include: source.InputPath, uniqueToProject: true); customBuild.AddSetting("Command", args.ToString(' '), condition: config.ConditionText); customBuild.AddSetting("Message", System.String.Format("Rccing {0}", System.IO.Path.GetFileName(source.InputPath.Parse())), condition: config.ConditionText); customBuild.AddSetting("Outputs", output, condition: config.ConditionText); }
IZipToolPolicy.Zip( ZipModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString zipOutputPath, Bam.Core.TokenizedString zipInputPath) { var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); var dir = sender.CreateTokenizedString("@dir($(0))", zipOutputPath); dir.Parse(); meta.CommonMetaData.AddDirectory(dir.ToString()); rule.AddTarget(zipOutputPath); var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); var args = new Bam.Core.StringArray(); args.Add(System.String.Format("cd {0};", zipInputPath.ToString())); args.Add( System.String.Format("{0} {1} -o {2} {3} {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), zipOutputPath.ToString(), "*", CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool) ) ); rule.AddShellCommand(args.ToString(' ')); }
IStripToolPolicy.Strip( StripModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString originalPath, Bam.Core.TokenizedString copiedPath) { var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); var sourceFilename = System.IO.Path.GetFileName(originalPath.Parse()); meta.CommonMetaData.Directories.AddUnique(sender.CreateTokenizedString("@dir($(0))", copiedPath).Parse()); rule.AddTarget(copiedPath, variableName: "strip_" + sourceFilename); var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); rule.AddShellCommand(System.String.Format("{0} {1} {2} -o {3} {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), originalPath.Parse(), copiedPath.Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); }
ICompilationPolicy.Compile( ObjectFile sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString objectFilePath, Bam.Core.Module source) { if (!sender.PerformCompilation) { return; } var commandLineArgs = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLineArgs); var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(objectFilePath); rule.AddPrerequisite(source, C.SourceFile.Key); var tool = sender.Tool as Bam.Core.ICommandLineTool; var command = new System.Text.StringBuilder(); command.AppendFormat("{0} {1} $< {2}", CommandLineProcessor.Processor.StringifyTool(tool), commandLineArgs.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(tool)); rule.AddShellCommand(command.ToString()); var objectFileDir = System.IO.Path.GetDirectoryName(objectFilePath.ToString()); meta.CommonMetaData.AddDirectory(objectFileDir); meta.CommonMetaData.ExtendEnvironmentVariables(tool.EnvironmentVariables); // add dependencies, such as procedurally generated headers foreach (var dep in sender.Dependents) { if (null == dep.MetaData) { continue; } if (dep is C.SourceFile) { continue; } var depMeta = dep.MetaData as MakeFileBuilder.MakeFileMeta; foreach (var depRule in depMeta.Rules) { depRule.ForEachTarget(target => { if (!target.IsPhony) { rule.AddPrerequisite(target.Path); } }); } } }
PathListToString( Bam.Core.StringArray pathList, string proFilePath) { var escapedPathList = new Bam.Core.StringArray(); foreach (var path in pathList) { escapedPathList.Add(FormatPath(path, proFilePath)); } return(escapedPathList.ToString("\\\n\t")); }
IChangeRPathPolicy.Change( ChangeRPathModule sender, Bam.Core.ExecutionContext context, CollatedFile source, string newRPath) { // add another shell command to the rule for copying the file var meta = source.MetaData as MakeFileBuilder.MakeFileMeta; var rule = meta.Rules[0]; var commandLine = new Bam.Core.StringArray(); commandLine.Add("-r"); rule.AddShellCommand(System.String.Format(@"{0} {1} {2} $@ {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), newRPath, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); }
IInstallNameToolPolicy.InstallName( InstallNameModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString oldName, Bam.Core.TokenizedString newName) { // add another shell command to the rule for copying the file var meta = sender.Source.MetaData as MakeFileBuilder.MakeFileMeta; var rule = meta.Rules[0]; var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); rule.AddShellCommand(System.String.Format(@"{0} {1} {2} $@ {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), newName.Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); }
void IRccGenerationPolicy.Rcc( RccGeneratedSource sender, Bam.Core.ExecutionContext context, Bam.Core.ICommandLineTool rccCompiler, Bam.Core.TokenizedString generatedRccSource, QRCFile source) { var encapsulating = sender.GetEncapsulatingReferencedModule(); var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta; var target = workspace.EnsureTargetExists(encapsulating); var configuration = target.GetConfiguration(encapsulating); var output = generatedRccSource.Parse(); var sourcePath = source.InputPath.Parse(); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("[[ ! -d {0} ]] && mkdir -p {0}", System.IO.Path.GetDirectoryName(output))); var args = new Bam.Core.StringArray(); args.Add(CommandLineProcessor.Processor.StringifyTool(rccCompiler)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add(System.String.Format("-o {0}", output)); args.Add(sourcePath); target.EnsureFileOfTypeExists(source.InputPath, XcodeBuilder.FileReference.EFileType.TextFile, relativePath: target.Project.GetRelativePathToProject(source.InputPath), explicitType: false); var rcc_commandLine = args.ToString(' '); commands.Add(System.String.Format("if [[ ! -e {0} || {1} -nt {0} ]]", output, sourcePath)); commands.Add("then"); commands.Add(System.String.Format("\techo {0}", rcc_commandLine)); commands.Add(System.String.Format("\t{0}", rcc_commandLine)); commands.Add("fi"); target.AddPreBuildCommands(commands, configuration); }
IZipToolPolicy.Zip( ZipModule sender, Bam.Core.ExecutionContext context, Bam.Core.TokenizedString zipOutputPath, Bam.Core.TokenizedString zipInputPath) { var encapsulating = sender.GetEncapsulatingReferencedModule(); var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution; var project = solution.EnsureProjectExists(encapsulating); var config = project.GetConfiguration(encapsulating); var args = new Bam.Core.StringArray(); args.Add(System.String.Format("cd {0} &&", zipInputPath.ToStringQuoteIfNecessary())); args.Add(CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add(System.String.Format("{0}", zipOutputPath.ToStringQuoteIfNecessary())); args.Add("*"); config.AddPreBuildCommand(args.ToString(' ')); }
void IGeneratedSourcePolicy.GenerateSource( GeneratedSourceModule sender, Bam.Core.ExecutionContext context, Bam.Core.ICommandLineTool compiler, Bam.Core.TokenizedString generatedFilePath) { var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(generatedFilePath); var buildTool = (compiler as Bam.Core.Module).MetaData as MakeFileBuilder.MakeFileMeta; rule.AddOrderOnlyDependency(System.String.Format("$({0})", buildTool.Rules[0].Targets[0].VariableName)); var commandLineArgs = new Bam.Core.StringArray(); // TODO: change this to a configuration directory really commandLineArgs.Add(Bam.Core.TokenizedString.Create("$(buildroot)", null).Parse()); commandLineArgs.Add("Generated"); var command = new System.Text.StringBuilder(); command.AppendFormat("{0} {1} $^", compiler.Executable.ParseAndQuoteIfNecessary(), commandLineArgs.ToString(' ')); rule.AddShellCommand(command.ToString()); }
void IRccGenerationPolicy.Rcc( RccGeneratedSource sender, Bam.Core.ExecutionContext context, Bam.Core.ICommandLineTool rccCompiler, Bam.Core.TokenizedString generatedRccSource, QRCFile source) { var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(generatedRccSource); rule.AddPrerequisite(source, C.HeaderFile.Key); var rccOutputPath = generatedRccSource.Parse(); var rccOutputDir = System.IO.Path.GetDirectoryName(rccOutputPath); var args = new Bam.Core.StringArray(); args.Add(CommandLineProcessor.Processor.StringifyTool(rccCompiler)); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(args); args.Add(System.String.Format("-o {0}", rccOutputPath)); args.Add(source.InputPath.Parse()); rule.AddShellCommand(args.ToString(' ')); meta.CommonMetaData.Directories.AddUnique(rccOutputDir); }
ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); var sourcePath = sender.SourcePath; var sourceFilename = System.IO.Path.GetFileName(sourcePath.Parse()); var topLevel = sender.GetEncapsulatingReferencedModule().GetType().Name; var senderType = sender.GetType().Name; var sourceType = (null != sender.SourceModule) ? sender.SourceModule.GetType().FullName : "publishroot"; var basename = sourceType + "_" + topLevel + "_" + senderType + "_" + sender.BuildEnvironment.Configuration.ToString() + "_"; var isSymLink = sender is CollatedSymbolicLink; var isDir = sender is CollatedDirectory; var isRenamedDir = sender.Tool is CopyFilePosix & sender.Macros["CopiedFilename"].IsAliased; if (isSymLink) { rule.AddTarget(sender.GeneratedPaths[CollatedObject.Key], variableName: basename + sourceFilename, isPhony: true); } else { if (isDir) { if (isRenamedDir) { var rename = sender.Macros["CopiedFilename"].Parse(); rule.AddTarget(Bam.Core.TokenizedString.CreateVerbatim(basename + rename), isPhony: true); } else { var targetName = sender.CreateTokenizedString("$(0)/@filename($(1))", sender.Macros["CopyDir"], sourcePath); rule.AddTarget(targetName, variableName: basename + sourceFilename); } } else { rule.AddTarget(sender.GeneratedPaths[CollatedObject.Key], variableName: basename + sourceFilename); } } meta.CommonMetaData.Directories.AddUnique(sender.Macros["CopyDir"].Parse()); var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); if (isSymLink) { rule.AddShellCommand(System.String.Format(@"{0} {1} {2} $@ {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sender.Macros["LinkTarget"].Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { if (isDir) { if (isRenamedDir) { rule.AddShellCommand(System.String.Format(@"{0} {1} $</* {2} {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sender.Macros["CopyDir"].Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { rule.AddShellCommand(System.String.Format(@"{0} {1} $< $(dir $@) {2}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } } else { rule.AddShellCommand(System.String.Format(@"{0} {1} $< $(dir $@) {2}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool)), ignoreErrors: !(sender as CollatedFile).FailWhenSourceDoesNotExist); } rule.AddPrerequisite(sourcePath); } }
public static void PostExecution() { var graph = Bam.Core.Graph.Instance; var commonMeta = graph.MetaData as MakeFileCommonMetaData; var makeEnvironment = new System.Text.StringBuilder(); var makeVariables = new System.Text.StringBuilder(); var makeRules = new System.Text.StringBuilder(); // delete suffix rules makeEnvironment.AppendLine(".SUFFIXES:"); foreach (var env in commonMeta.Environment) { makeEnvironment.AppendFormat("{0}:={1}", env.Key, env.Value.ToString(System.IO.Path.PathSeparator)); makeEnvironment.AppendLine(); } if (commonMeta.Directories.Count > 0) { makeVariables.Append("DIRS:="); foreach (var dir in commonMeta.Directories) { makeVariables.AppendFormat("{0} ", dir); } makeVariables.AppendLine(); } // all rule makeRules.Append("all:"); var allPrerequisites = new Bam.Core.StringArray(); // loop over all ranks, until the top-most modules with Make metadata are added to 'all' // this allows skipping over any upper modules without Make policies foreach (var rank in graph) { foreach (var module in rank) { var metadata = module.MetaData as MakeFileMeta; if (null == metadata) { continue; } foreach (var rule in metadata.Rules) { // TODO: could just exit from the loop after the first iteration if (!rule.IsFirstRule) { continue; } rule.AppendTargetNames(allPrerequisites); } } if (allPrerequisites.Any()) { break; } } makeRules.AppendLine(allPrerequisites.ToString(' ')); // directory direction rule makeRules.AppendLine("$(DIRS):"); if (Bam.Core.OSUtilities.IsWindowsHosting) { makeRules.AppendLine("\tmkdir $@"); } else { makeRules.AppendLine("\tmkdir -pv $@"); } // clean rule makeRules.AppendLine(".PHONY: clean"); makeRules.AppendLine("clean:"); makeRules.AppendLine("\t@rm -frv $(DIRS)"); foreach (var rank in graph.Reverse()) { foreach (var module in rank) { var metadata = module.MetaData as MakeFileMeta; if (null == metadata) { continue; } foreach (var rule in metadata.Rules) { rule.WriteVariables(makeVariables); rule.WriteRules(makeRules); } } } Bam.Core.Log.DebugMessage("MAKEFILE CONTENTS: BEGIN"); Bam.Core.Log.DebugMessage(makeEnvironment.ToString()); Bam.Core.Log.DebugMessage(makeVariables.ToString()); Bam.Core.Log.DebugMessage(makeRules.ToString()); Bam.Core.Log.DebugMessage("MAKEFILE CONTENTS: END"); var makeFilePath = Bam.Core.TokenizedString.Create("$(buildroot)/Makefile", null); makeFilePath.Parse(); using (var writer = new System.IO.StreamWriter(makeFilePath.ToString())) { writer.Write(makeEnvironment.ToString()); writer.Write(makeVariables.ToString()); writer.Write(makeRules.ToString()); } Bam.Core.Log.Info("Successfully created MakeFile for package '{0}'\n\t{1}", graph.MasterPackage.Name, makeFilePath); }
ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { var sourcePath = sender.SourcePath; if (null == sender.Reference) { // the main file is not copied anywhere, as we copy required files around it where Xcode wrote the main file // this is managed by the Collation class, querying the build mode for where publishing is relative to // ignore any subdirectory on this module // convert the executable into an app bundle, if EPublishingType.WindowedApplication has been used as the type if ((sender.SubDirectory != null) && sender.SubDirectory.Parse().Contains(".app/")) { var target = sender.SourceModule.MetaData as XcodeBuilder.Target; target.MakeApplicationBundle(); } return; } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); var destinationPath = sender.Macros["CopyDir"].Parse(); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("[[ ! -d {0} ]] && mkdir -p {0}", destinationPath)); if (sender.SourceModule != null && sender.SourceModule.MetaData != null) { if ((null != sender.Reference) && (sender.SourceModule.PackageDefinition == sender.Reference.PackageDefinition) && (null == sender.Reference.SubDirectory) && (sender.SubDirectory.Parse() == ".")) { // special case that the module output is already in the right directory at build return; } commands.Add(System.String.Format("{0} {1} $CONFIGURATION_BUILD_DIR/$EXECUTABLE_NAME {2} {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), destinationPath, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); var target = sender.SourceModule.MetaData as XcodeBuilder.Target; var configuration = target.GetConfiguration(sender.SourceModule); target.AddPostBuildCommands(commands, configuration); } else { var isSymlink = (sender is CollatedSymbolicLink); var destinationFolder = "$CONFIGURATION_BUILD_DIR"; if (sender.Reference != null) { destinationFolder = "$CONFIGURATION_BUILD_DIR/$EXECUTABLE_FOLDER_PATH"; } if (isSymlink) { commands.Add(System.String.Format("{0} {1} {2} {3}/{4} {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sender.Macros["LinkTarget"].Parse(), destinationFolder, sender.CreateTokenizedString("$(0)/@filename($(1))", sender.SubDirectory, sender.SourcePath).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { if (sender is CollatedDirectory) { var copySource = sourcePath.Parse(); if (sender.Macros["CopiedFilename"].IsAliased) { copySource = System.String.Format("{0}/*", copySource); } commands.Add(System.String.Format("{0} {1} {2} {3}/{4}/ {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), copySource, destinationFolder, sender.CreateTokenizedString("$(0)/@ifnotempty($(CopiedFilename),$(CopiedFilename),@filename($(1)))", sender.SubDirectory, sourcePath).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { commands.Add(System.String.Format("{0} {1} {2} {3}/{4}/ {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.Parse(), destinationFolder, sender.SubDirectory.Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } } var target = sender.Reference.SourceModule.MetaData as XcodeBuilder.Target; var configuration = target.GetConfiguration(sender.Reference.SourceModule); target.AddPostBuildCommands(commands, configuration); } }
ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { var sourcePath = sender.SourcePath; if (null == sender.Reference) { if ((null != sender.SourceModule.MetaData) || (sender.SourceModule is CollatedObject)) { // the main file is not copied anywhere, as we copy required files around it where VS wrote the main file // this is managed by the Collation class, querying the build mode for where publishing is relative to // ignore any subdirectory on this module // could also be a DebugSymbols or Stripped copy, in which case, ignore it return; } else { // the main reference file was a prebuilt - so create a new project to handle copying files var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution; var project = solution.EnsureProjectExists(sender.SourceModule); var config = project.GetConfiguration(sender.SourceModule); config.SetType(VSSolutionBuilder.VSProjectConfiguration.EType.Utility); config.SetOutputPath(sender.Macros["CopyDir"]); config.EnableIntermediatePath(); } } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); if (sender.SourceModule != null && sender.SourceModule.MetaData != null && VSSolutionBuilder.VSProject.IsBuildable(sender.SourceModule)) { var destinationPath = sender.Macros["CopyDir"].Parse(); var project = sender.SourceModule.MetaData as VSSolutionBuilder.VSProject; var config = project.GetConfiguration(sender.SourceModule); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("IF NOT EXIST {0} MKDIR {0}", destinationPath)); if (config.Type != VSSolutionBuilder.VSProjectConfiguration.EType.Utility) { commands.Add(System.String.Format(@"{0} {1} $(OutputPath)$(TargetFileName) {2} {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), destinationPath, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); config.AddPostBuildCommands(commands); } else { commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir).\ {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); config.AddPreBuildCommands(commands); } } else { var commands = new Bam.Core.StringArray(); if (sender is CollatedDirectory) { // Windows XCOPY requires the directory name to be added to the destination, while Posix cp does not commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir){3}\ {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), sender.CreateTokenizedString("$(0)/@ifnotempty($(CopiedFilename),$(CopiedFilename),@filename($(1)))", sender.SubDirectory, sourcePath).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir){3}\ {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), sender.SubDirectory, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } var project = sender.Reference.SourceModule.MetaData as VSSolutionBuilder.VSProject; var config = project.GetConfiguration(sender.Reference.SourceModule); if (config.Type != VSSolutionBuilder.VSProjectConfiguration.EType.Utility) { config.AddPostBuildCommands(commands); } else { config.AddPreBuildCommands(commands); } } }
Serialize() { var document = new System.Xml.XmlDocument(); var projectEl = this.CreateRootProject(document); projectEl.SetAttribute("ToolsVersion", "4.0"); // TODO: get this number from VisualC var filtersEl = document.CreateVSItemGroup(parentEl: projectEl); foreach (var filter in this.Filters) { var filterEl = document.CreateVSElement("Filter", parentEl: filtersEl); filterEl.SetAttribute("Include", filter.Key); document.CreateVSElement("UniqueIdentifier", new DeterministicGuid("VSFilter" + filter.Key).Guid.ToString("B").ToUpper(), parentEl: filterEl); var filesEl = document.CreateVSItemGroup(parentEl: projectEl); var extensions = new Bam.Core.StringArray(); foreach (var setting in filter.Value) { var path = setting.Include; var extension = System.IO.Path.GetExtension(path.Parse()).TrimStart(new[] { '.' }); extensions.AddUnique(extension); setting.Serialize(document, filesEl); } if (extensions.Count > 0) { document.CreateVSElement("Extensions", extensions.ToString(';'), parentEl: filterEl); } } return document; }
Execute( Bam.Core.ExecutionContext context, string executablePath, Bam.Core.StringArray commandLineArguments = null, string workingDirectory = null, Bam.Core.StringArray inheritedEnvironmentVariables = null, System.Collections.Generic.Dictionary <string, Bam.Core.TokenizedStringArray> addedEnvironmentVariables = null, string useResponseFileOption = null) { var processStartInfo = new System.Diagnostics.ProcessStartInfo(); processStartInfo.FileName = executablePath; processStartInfo.ErrorDialog = true; if (null != workingDirectory) { processStartInfo.WorkingDirectory = workingDirectory; } var cachedEnvVars = new System.Collections.Generic.Dictionary <string, string>(); // first get the inherited environment variables from the system environment if (null != inheritedEnvironmentVariables) { int envVarCount; if (inheritedEnvironmentVariables.Count == 1 && inheritedEnvironmentVariables[0] == "*") { foreach (System.Collections.DictionaryEntry envVar in processStartInfo.EnvironmentVariables) { cachedEnvVars.Add(envVar.Key as string, envVar.Value as string); } } else if (inheritedEnvironmentVariables.Count == 1 && System.Int32.TryParse(inheritedEnvironmentVariables[0], out envVarCount) && envVarCount < 0) { envVarCount += processStartInfo.EnvironmentVariables.Count; foreach (var envVar in processStartInfo.EnvironmentVariables.Cast <System.Collections.DictionaryEntry>().OrderBy(item => item.Key)) { cachedEnvVars.Add(envVar.Key as string, envVar.Value as string); --envVarCount; if (0 == envVarCount) { break; } } } else { foreach (var envVar in inheritedEnvironmentVariables) { if (!processStartInfo.EnvironmentVariables.ContainsKey(envVar)) { Bam.Core.Log.Info("Environment variable '{0}' does not exist", envVar); continue; } cachedEnvVars.Add(envVar, processStartInfo.EnvironmentVariables[envVar]); } } } processStartInfo.EnvironmentVariables.Clear(); if (null != inheritedEnvironmentVariables) { foreach (var envVar in cachedEnvVars) { processStartInfo.EnvironmentVariables[envVar.Key] = envVar.Value; } } if (null != addedEnvironmentVariables) { foreach (var envVar in addedEnvironmentVariables) { processStartInfo.EnvironmentVariables[envVar.Key] = envVar.Value.ToString(System.IO.Path.PathSeparator); } } processStartInfo.UseShellExecute = false; // to redirect IO streams processStartInfo.RedirectStandardOutput = true; processStartInfo.RedirectStandardError = true; processStartInfo.RedirectStandardInput = true; var arguments = commandLineArguments != null?commandLineArguments.ToString(' ') : string.Empty; string responseFilePath = null; if (Bam.Core.OSUtilities.IsWindowsHosting) { //TODO: should this include the length of the executable path too? if (arguments.Length >= 32767) { if (null == useResponseFileOption) { throw new Bam.Core.Exception("Command line is {0} characters long, but response files are not supported by the tool {1}", arguments.Length, executablePath); } responseFilePath = Bam.Core.IOWrapper.CreateTemporaryFile(); using (System.IO.StreamWriter writer = new System.IO.StreamWriter(responseFilePath)) { Bam.Core.Log.DebugMessage("Written response file {0} containing:\n{1}", responseFilePath, arguments); // escape any back slashes writer.WriteLine(arguments.Replace(@"\", @"\\")); } arguments = System.String.Format("{0}{1}", useResponseFileOption, responseFilePath); } } processStartInfo.Arguments = arguments; Bam.Core.Log.Detail("{0} {1}", processStartInfo.FileName, processStartInfo.Arguments); // useful debugging of the command line processor Bam.Core.Log.DebugMessage("Working directory: '{0}'", processStartInfo.WorkingDirectory); if (processStartInfo.EnvironmentVariables.Count > 0) { Bam.Core.Log.DebugMessage("Environment variables:"); foreach (var envVar in processStartInfo.EnvironmentVariables.Cast <System.Collections.DictionaryEntry>().OrderBy(item => item.Key)) { Bam.Core.Log.DebugMessage("\t{0} = {1}", envVar.Key, envVar.Value); } } System.Diagnostics.Process process = null; int exitCode = -1; try { process = new System.Diagnostics.Process(); process.StartInfo = processStartInfo; process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(context.OutputDataReceived); process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(context.ErrorDataReceived); process.Start(); process.StandardInput.Close(); } catch (System.ComponentModel.Win32Exception ex) { throw new Bam.Core.Exception("'{0}': process filename '{1}'", ex.Message, processStartInfo.FileName); } if (null != process) { process.BeginOutputReadLine(); process.BeginErrorReadLine(); // TODO: need to poll for an external cancel op? // poll for the process to exit, as some processes seem to get stuck (hdiutil attach, for example) while (!process.HasExited) { process.WaitForExit(2000); } // this additional WaitForExit appears to be needed in order to finish reading the output and error streams asynchronously // without it, output is missing from a Native build when executed in many threads process.WaitForExit(); exitCode = process.ExitCode; //Bam.Core.Log.DebugMessage("Tool exit code: {0}", exitCode); process.Close(); } // delete once the process has finished, or never started if (null != responseFilePath) { System.IO.File.Delete(responseFilePath); } if (exitCode != 0) { var message = new System.Text.StringBuilder(); message.AppendFormat("Command failed: {0} {1}", processStartInfo.FileName, processStartInfo.Arguments); message.AppendLine(); if (null != responseFilePath) { message.AppendLine("Response file contained:"); message.AppendLine(arguments); } message.AppendFormat("Command exit code: {0}", exitCode); message.AppendLine(); throw new Bam.Core.Exception(message.ToString()); } }
public object Build( CodeGenTest2.CodeGenModule moduleToBuild, out System.Boolean success) { var codeGenModuleModule = moduleToBuild as Bam.Core.BaseModule; var node = codeGenModuleModule.OwningNode; var target = node.Target; var codeGenModuleOptions = codeGenModuleModule.Options; var toolOptions = codeGenModuleOptions as CodeGenTest2.CodeGenOptionCollection; var tool = target.Toolset.Tool(typeof(CodeGenTest2.ICodeGenTool)); var toolExePath = tool.Executable((Bam.Core.BaseTarget)target); var inputFiles = new Bam.Core.StringArray(); inputFiles.Add(toolExePath); // at this point, we know the node outputs need building // create all directories required var dirsToCreate = moduleToBuild.Locations.FilterByType(Bam.Core.ScaffoldLocation.ETypeHint.Directory, Bam.Core.Location.EExists.WillExist); var commandLineBuilder = new Bam.Core.StringArray(); if (toolOptions is CommandLineProcessor.ICommandLineSupport) { var commandLineOption = toolOptions as CommandLineProcessor.ICommandLineSupport; commandLineOption.ToCommandLineArguments(commandLineBuilder, target, null); } else { throw new Bam.Core.Exception("Moc options does not support command line translation"); } var recipes = new Bam.Core.StringArray(); if (toolExePath.Contains(" ")) { recipes.Add("\"" + toolExePath + "\" " + commandLineBuilder.ToString()); } else { recipes.Add(toolExePath + " " + commandLineBuilder.ToString()); } var makeFilePath = MakeFileBuilder.GetMakeFilePathName(node); System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(makeFilePath)); Bam.Core.Log.DebugMessage("Makefile : '{0}'", makeFilePath); var makeFile = new MakeFile(node, this.topLevelMakeFilePath); var rule = new MakeFileRule( moduleToBuild, CodeGenTest2.CodeGenModule.OutputFile, node.UniqueModuleName, dirsToCreate, null, inputFiles, recipes); rule.OutputLocationKeys = new Bam.Core.Array<Bam.Core.LocationKey>(CodeGenTest2.CodeGenModule.OutputFile); makeFile.RuleArray.Add(rule); using (var makeFileWriter = new System.IO.StreamWriter(makeFilePath)) { makeFile.Write(makeFileWriter); } System.Collections.Generic.Dictionary<string, Bam.Core.StringArray> environment = null; if (tool is Bam.Core.IToolEnvironmentVariables) { environment = (tool as Bam.Core.IToolEnvironmentVariables).Variables((Bam.Core.BaseTarget)target); } var returnData = new MakeFileData(makeFilePath, makeFile.ExportedTargets, makeFile.ExportedVariables, environment); success = true; return returnData; }
ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { if (sender.Ignore) { return; } var collatedInterface = sender as ICollatedObject; var arePostBuildCommands = true; Bam.Core.Module sourceModule; if (null != collatedInterface.SourceModule) { sourceModule = collatedInterface.SourceModule; if (null == sourceModule.MetaData) { // this can happen for prebuilt frameworks sourceModule = collatedInterface.Anchor.SourceModule; } } else { if (null != collatedInterface.Anchor) { // usually preexisting files that are published as part of an executable's distribution // in which case, their anchor is the executable (or a similar binary) sourceModule = collatedInterface.Anchor.SourceModule; } else { if (sender is CollatedPreExistingFile) { sourceModule = (sender as CollatedPreExistingFile).ParentOfCollationModule; var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta; workspace.EnsureTargetExists(sourceModule); arePostBuildCommands = false; } else { throw new Bam.Core.Exception("No anchor set on '{0}' with source path '{1}'", sender.GetType().ToString(), sender.SourcePath); } } } var target = sourceModule.MetaData as XcodeBuilder.Target; if (sender.IsAnchor && (null != collatedInterface.SourceModule)) { if (sender.IsAnchorAnApplicationBundle) { // application bundles are a different output type in Xcode target.MakeApplicationBundle(); } // since all dependents are copied _beside_ their anchor, the anchor copy is a no-op return; } if (sender.IsInAnchorPackage && (null != collatedInterface.SourceModule) && !(collatedInterface.Anchor as CollatedObject).IsAnchorAnApplicationBundle) { // additionally, any module-based dependents in the same package as the anchor do not need copying as they // are built into the right directory (since Xcode module build dirs do not include the module name) return; } var copyFileTool = sender.Tool as CopyFileTool; string copySourcePath; string destinationDir; copyFileTool.convertPaths( sender, sender.SourcePath, collatedInterface.PublishingDirectory, out copySourcePath, out destinationDir); if (null == sender.PreExistingSourcePath) { Bam.Core.Log.DebugMessage("** {0}[{1}]:\t'{2}' -> '{3}'", collatedInterface.SourceModule.ToString(), collatedInterface.SourcePathKey.ToString(), copyFileTool.escapePath(copySourcePath), copyFileTool.escapePath(destinationDir)); } else { Bam.Core.Log.DebugMessage("** {0}: '{1}' -> '{2}'", sender, copyFileTool.escapePath(copySourcePath), copyFileTool.escapePath(destinationDir)); } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("[[ ! -d {0} ]] && mkdir -p {0}", copyFileTool.escapePath(destinationDir))); var configuration = target.GetConfiguration(sourceModule); commands.Add(System.String.Format("{0} {1} {2} {3} {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), copyFileTool.escapePath(copySourcePath), copyFileTool.escapePath(destinationDir), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); if (!target.isUtilityType && arePostBuildCommands) { target.AddPostBuildCommands(commands, configuration); } else { target.AddPreBuildCommands(commands, configuration); } }
ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { var sourcePath = sender.SourcePath; if (null == sender.Reference) { if ((null != sender.SourceModule.MetaData) || (sender.SourceModule is CollatedObject)) { // the main file is not copied anywhere, as we copy required files around it where Xcode wrote the main file // this is managed by the Collation class, querying the build mode for where publishing is relative to // ignore any subdirectory on this module // convert the executable into an app bundle, if EPublishingType.WindowedApplication has been used as the type if ((sender.SubDirectory != null) && sender.SubDirectory.Parse().Contains(".app/")) { var target = sender.SourceModule.MetaData as XcodeBuilder.Target; target.MakeApplicationBundle(); } return; } else { // the main reference file was a prebuilt - so create a new project to handle copying files var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta; var target = workspace.EnsureTargetExists(sender.SourceModule); var configuration = target.GetConfiguration(sender.SourceModule); target.Type = XcodeBuilder.Target.EProductType.Utility; configuration.SetProductName(sender.SourceModule.Macros["modulename"]); //Bam.Core.Log.MessageAll("Configuration {0} for {1}", configuration.Name, sender.SourceModule.ToString()); } } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); var destinationPath = sender.Macros["CopyDir"].Parse(); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("[[ ! -d {0} ]] && mkdir -p {0}", destinationPath)); if (sender.SourceModule != null && sender.SourceModule.MetaData != null) { if ((null != sender.Reference) && (null != sender.Reference.SourceModule) && (sender.SourceModule.PackageDefinition == sender.Reference.SourceModule.PackageDefinition) && (null == sender.Reference.SubDirectory) && (sender.SubDirectory.Parse() == ".")) { // special case that the module output is already in the right directory at build return; } var target = sender.SourceModule.MetaData as XcodeBuilder.Target; if (target.Type != XcodeBuilder.Target.EProductType.Utility) { commands.Add(System.String.Format("{0} {1} $CONFIGURATION_BUILD_DIR/$EXECUTABLE_NAME {2} {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), destinationPath, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { commands.Add(System.String.Format("{0} {1} {2} {3} {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.Parse(), destinationPath, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } var configuration = target.GetConfiguration(sender.SourceModule); if (target.Type != XcodeBuilder.Target.EProductType.Utility) { target.AddPostBuildCommands(commands, configuration); } else { target.AddPreBuildCommands(commands, configuration); } } else { var target = sender.Reference.SourceModule.MetaData as XcodeBuilder.Target; var isSymlink = (sender is CollatedSymbolicLink); var destinationFolder = "$CONFIGURATION_BUILD_DIR"; if (sender.Reference != null) { destinationFolder = "$CONFIGURATION_BUILD_DIR/$EXECUTABLE_FOLDER_PATH"; } if (target.Type == XcodeBuilder.Target.EProductType.Utility) { destinationFolder = destinationPath; } if (isSymlink) { commands.Add(System.String.Format("{0} {1} {2} {3}/{4} {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sender.Macros["LinkTarget"].Parse(), destinationFolder, sender.CreateTokenizedString("$(0)/@filename($(1))", sender.SubDirectory, sender.SourcePath).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { if (sender is CollatedDirectory) { var copySource = sourcePath.Parse(); if (sender.Macros["CopiedFilename"].IsAliased) { copySource = System.String.Format("{0}/*", copySource); } commands.Add(System.String.Format("{0} {1} {2} {3}/{4}/ {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), copySource, destinationFolder, sender.CreateTokenizedString("$(0)/@ifnotempty($(CopiedFilename),$(CopiedFilename),)", sender.SubDirectory).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { commands.Add(System.String.Format("{0} {1} {2} {3}/{4}/ {5}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.Parse(), destinationFolder, sender.SubDirectory.Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } } var configuration = target.GetConfiguration(sender.Reference.SourceModule); if (target.Type != XcodeBuilder.Target.EProductType.Utility) { target.AddPostBuildCommands(commands, configuration); } else { target.AddPreBuildCommands(commands, configuration); } } }
public static void PostExecution() { var graph = Bam.Core.Graph.Instance; var commonMeta = graph.MetaData as MakeFileCommonMetaData; var makeEnvironment = new System.Text.StringBuilder(); var makeVariables = new System.Text.StringBuilder(); var makeRules = new System.Text.StringBuilder(); // delete suffix rules makeEnvironment.AppendLine(".SUFFIXES:"); commonMeta.ExportEnvironment(makeEnvironment); commonMeta.ExportDirectories(makeVariables); // all rule var prerequisitesOfTargetAll = new Bam.Core.StringArray(); // loop over all metadata, until the top-most modules with Make metadata are added to 'all' // this allows skipping over any upper modules without Make policies foreach (var metadata in allMeta) { foreach (var rule in metadata.Rules) { rule.AppendAllPrerequisiteTargetNames(prerequisitesOfTargetAll); } } makeRules.Append("all:"); makeRules.AppendLine(prerequisitesOfTargetAll.ToString(' ')); // directory direction rule makeRules.AppendLine("$(DIRS):"); if (Bam.Core.OSUtilities.IsWindowsHosting) { makeRules.AppendLine("\tmkdir $@"); } else { makeRules.AppendLine("\tmkdir -pv $@"); } // clean rule makeRules.AppendLine(".PHONY: clean"); makeRules.AppendLine("clean:"); if (Bam.Core.OSUtilities.IsWindowsHosting) { makeRules.AppendLine("\t-cmd.exe /C RMDIR /S /Q $(DIRS)"); } else { makeRules.AppendLine("\t@rm -frv $(DIRS)"); } // write all variables and rules foreach (var metadata in allMeta) { foreach (var rule in metadata.Rules) { rule.WriteVariables(makeVariables); rule.WriteRules(makeRules); } } Bam.Core.Log.DebugMessage("MAKEFILE CONTENTS: BEGIN"); Bam.Core.Log.DebugMessage(makeEnvironment.ToString()); Bam.Core.Log.DebugMessage(makeVariables.ToString()); Bam.Core.Log.DebugMessage(makeRules.ToString()); Bam.Core.Log.DebugMessage("MAKEFILE CONTENTS: END"); var makeFilePath = Bam.Core.TokenizedString.Create("$(buildroot)/Makefile", null); makeFilePath.Parse(); using (var writer = new System.IO.StreamWriter(makeFilePath.ToString())) { writer.Write(makeEnvironment.ToString()); writer.Write(makeVariables.ToString()); writer.Write(makeRules.ToString()); } Bam.Core.Log.Info("Successfully created MakeFile for package '{0}'\n\t{1}", graph.MasterPackage.Name, makeFilePath); }
ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { if (sender.Ignore) { return; } var collatedInterface = sender as ICollatedObject; var copyFileTool = sender.Tool as CopyFileTool; string copySourcePath; string destinationDir; copyFileTool.convertPaths( sender, sender.SourcePath, collatedInterface.PublishingDirectory, out copySourcePath, out destinationDir); if (null == sender.PreExistingSourcePath) { Bam.Core.Log.DebugMessage("** {0}[{1}]:\t'{2}' -> '{3}'", collatedInterface.SourceModule.ToString(), collatedInterface.SourcePathKey.ToString(), copySourcePath, destinationDir); } else { Bam.Core.Log.DebugMessage("** {0}: '{1}' -> '{2}'", sender, copySourcePath, destinationDir); } var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); var topLevel = sender.GetEncapsulatingReferencedModule().GetType().Name; var senderType = sender.GetType().Name; var sourceType = (null != collatedInterface.SourceModule) ? collatedInterface.SourceModule.GetType().FullName : "publishroot"; var basename = sourceType + "_" + topLevel + "_" + senderType + "_" + sender.BuildEnvironment.Configuration.ToString() + "_"; var sourceFilename = System.IO.Path.GetFileName(sender.SourcePath.ToString()); var isPosixLeafRename = copySourcePath.EndsWith("*"); string prerequisitePath; var destinationPath = sender.GeneratedPaths[CollatedObject.Key]; if (isPosixLeafRename) { sourceFilename = System.String.Format("{0}-to-{1}", sourceFilename, sender.Macros["RenameLeaf"].ToString()); prerequisitePath = System.IO.Path.GetDirectoryName(copySourcePath); // there would be multiple commands for the target directory if this was // added to meta.CommonMetaData rule.AddShellCommand("mkdir -p $@"); } else { prerequisitePath = copySourcePath; meta.CommonMetaData.AddDirectory(destinationDir); } rule.AddTarget(destinationPath, variableName: basename + sourceFilename); var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); if (isPosixLeafRename) { rule.AddShellCommand(System.String.Format(@"{0} {1} $</* $@ {2}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { rule.AddShellCommand(System.String.Format(@"{0} {1} $< $(dir $@) {2}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } rule.AddPrerequisite(Bam.Core.TokenizedString.CreateVerbatim(prerequisitePath)); }
IGeneratedSourcePolicy.GenerateSource( GeneratedSourceModule sender, Bam.Core.ExecutionContext context, Bam.Core.ICommandLineTool compiler, Bam.Core.TokenizedString generatedFilePath) { var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(generatedFilePath); var buildTool = (compiler as Bam.Core.Module).MetaData as MakeFileBuilder.MakeFileMeta; rule.AddOrderOnlyDependency(System.String.Format("$({0})", buildTool.Rules[0].FirstTarget.VariableName)); // TODO: change this to a configuration directory really var output_dir = Bam.Core.IOWrapper.EncloseSpaceContainingPathWithDoubleQuotes(Bam.Core.Graph.Instance.BuildRoot); var commandLineArgs = new Bam.Core.StringArray(); commandLineArgs.Add(output_dir); commandLineArgs.Add("Generated"); var command = new System.Text.StringBuilder(); command.AppendFormat("{0} {1} $^", compiler.Executable.ToStringQuoteIfNecessary(), commandLineArgs.ToString(' ')); rule.AddShellCommand(command.ToString()); }
public object Build( CSharp.Assembly moduleToBuild, out System.Boolean success) { var assemblyModule = moduleToBuild as Bam.Core.BaseModule; var node = assemblyModule.OwningNode; var target = node.Target; var assemblyOptions = assemblyModule.Options; var options = assemblyOptions as CSharp.OptionCollection; var inputVariables = new MakeFileVariableDictionary(); if (node.ExternalDependents != null) { foreach (var dependentNode in node.ExternalDependents) { if (null != dependentNode.Data) { continue; } var keyFilters = new Bam.Core.Array<Bam.Core.LocationKey>( CSharp.Assembly.OutputFile ); var assemblyLocations = new Bam.Core.LocationArray(); dependentNode.FilterOutputLocations(keyFilters, assemblyLocations); var data = dependentNode.Data as MakeFileData; var csharpOptions = options as CSharp.IOptions; foreach (var loc in assemblyLocations) { csharpOptions.References.Add(loc.GetSinglePath()); inputVariables.Add(CSharp.Assembly.OutputFile, data.VariableDictionary[CSharp.Assembly.OutputDir]); } } } var sourceFiles = new Bam.Core.StringArray(); var fields = moduleToBuild.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); foreach (var field in fields) { // C# files { var sourceFileAttributes = field.GetCustomAttributes(typeof(Bam.Core.SourceFilesAttribute), false); if (null != sourceFileAttributes && sourceFileAttributes.Length > 0) { var sourceField = field.GetValue(moduleToBuild); if (sourceField is Bam.Core.Location) { var file = sourceField as Bam.Core.Location; var absolutePath = file.GetSinglePath(); if (!System.IO.File.Exists(absolutePath)) { throw new Bam.Core.Exception("Source file '{0}' does not exist", absolutePath); } sourceFiles.Add(absolutePath); } else if (sourceField is Bam.Core.FileCollection) { var sourceCollection = sourceField as Bam.Core.FileCollection; // TODO: convert to var foreach (Bam.Core.Location location in sourceCollection) { var absolutePath = location.GetSinglePath(); if (!System.IO.File.Exists(absolutePath)) { throw new Bam.Core.Exception("Source file '{0}' does not exist", absolutePath); } sourceFiles.Add(absolutePath); } } else { throw new Bam.Core.Exception("Field '{0}' of '{1}' should be of type Bam.Core.File or Bam.Core.FileCollection, not '{2}'", field.Name, node.ModuleName, sourceField.GetType().ToString()); } } } // WPF application definition .xaml file { var xamlFileAttributes = field.GetCustomAttributes(typeof(CSharp.ApplicationDefinitionAttribute), false); if (null != xamlFileAttributes && xamlFileAttributes.Length > 0) { var sourceField = field.GetValue(moduleToBuild); if (sourceField is Bam.Core.Location) { var file = sourceField as Bam.Core.Location; var absolutePath = file.GetSinglePath(); if (!System.IO.File.Exists(absolutePath)) { throw new Bam.Core.Exception("Application definition file '{0}' does not exist", absolutePath); } var csPath = absolutePath + ".cs"; if (!System.IO.File.Exists(csPath)) { throw new Bam.Core.Exception("Associated source file '{0}' to application definition file '{1}' does not exist", csPath, absolutePath); } sourceFiles.Add(csPath); } else if (sourceField is Bam.Core.FileCollection) { var sourceCollection = sourceField as Bam.Core.FileCollection; if (sourceCollection.Count != 1) { throw new Bam.Core.Exception("There can be only one application definition"); } // TODO: convert to var foreach (string absolutePath in sourceCollection) { if (!System.IO.File.Exists(absolutePath)) { throw new Bam.Core.Exception("Application definition file '{0}' does not exist", absolutePath); } var csPath = absolutePath + ".cs"; if (!System.IO.File.Exists(csPath)) { throw new Bam.Core.Exception("Associated source file '{0}' to application definition file '{1}' does not exist", csPath, absolutePath); } sourceFiles.Add(csPath); } } else { throw new Bam.Core.Exception("Field '{0}' of '{1}' should be of type Bam.Core.File or Bam.Core.FileCollection, not '{2}'", field.Name, node.ModuleName, sourceField.GetType().ToString()); } } } // WPF page .xaml files { var xamlFileAttributes = field.GetCustomAttributes(typeof(CSharp.PagesAttribute), false); if (null != xamlFileAttributes && xamlFileAttributes.Length > 0) { var sourceField = field.GetValue(moduleToBuild); if (sourceField is Bam.Core.Location) { var file = sourceField as Bam.Core.Location; var absolutePath = file.GetSinglePath(); if (!System.IO.File.Exists(absolutePath)) { throw new Bam.Core.Exception("Page file '{0}' does not exist", absolutePath); } var csPath = absolutePath + ".cs"; if (!System.IO.File.Exists(csPath)) { throw new Bam.Core.Exception("Associated source file '{0}' to page file '{1}' does not exist", csPath, absolutePath); } sourceFiles.Add(csPath); } else if (sourceField is Bam.Core.FileCollection) { var sourceCollection = sourceField as Bam.Core.FileCollection; if (sourceCollection.Count != 1) { throw new Bam.Core.Exception("There can be only one page file"); } // TODO: convert to var foreach (string absolutePath in sourceCollection) { if (!System.IO.File.Exists(absolutePath)) { throw new Bam.Core.Exception("Page file '{0}' does not exist", absolutePath); } var csPath = absolutePath + ".cs"; if (!System.IO.File.Exists(csPath)) { throw new Bam.Core.Exception("Associated source file '{0}' to page file '{1}' does not exist", csPath, absolutePath); } sourceFiles.Add(csPath); } } else { throw new Bam.Core.Exception("Field '{0}' of '{1}' should be of type Bam.Core.File or Bam.Core.FileCollection, not '{2}'", field.Name, node.ModuleName, sourceField.GetType().ToString()); } } } } if (0 == sourceFiles.Count) { throw new Bam.Core.Exception("There were no source files specified for the module '{0}'", node.ModuleName); } // at this point, we know the node outputs need building // create all directories required var dirsToCreate = moduleToBuild.Locations.FilterByType(Bam.Core.ScaffoldLocation.ETypeHint.Directory, Bam.Core.Location.EExists.WillExist); var commandLineBuilder = new Bam.Core.StringArray(); if (options is CommandLineProcessor.ICommandLineSupport) { var commandLineOption = options as CommandLineProcessor.ICommandLineSupport; commandLineOption.ToCommandLineArguments(commandLineBuilder, target, null); } else { throw new Bam.Core.Exception("Compiler options does not support command line translation"); } foreach (var source in sourceFiles) { if (source.Contains(" ")) { commandLineBuilder.Add(System.String.Format("\"{0}\"", source)); } else { commandLineBuilder.Add(source); } } var compilerInstance = target.Toolset.Tool(typeof(CSharp.ICSharpCompilerTool)); var executablePath = compilerInstance.Executable((Bam.Core.BaseTarget)target); var recipes = new Bam.Core.StringArray(); if (executablePath.Contains(" ")) { recipes.Add(System.String.Format("\"{0}\" {1}", executablePath, commandLineBuilder.ToString(' '))); } else { recipes.Add(System.String.Format("{0} {1}", executablePath, commandLineBuilder.ToString(' '))); } var makeFile = new MakeFile(node, this.topLevelMakeFilePath); var rule = new MakeFileRule( moduleToBuild, CSharp.Assembly.OutputFile, node.UniqueModuleName, dirsToCreate, inputVariables, null, recipes); var toolOutputLocKeys = compilerInstance.OutputLocationKeys(moduleToBuild); var outputFileLocations = moduleToBuild.Locations.Keys(Bam.Core.ScaffoldLocation.ETypeHint.File, Bam.Core.Location.EExists.WillExist); var outputFileLocationsOfInterest = outputFileLocations.Intersect(toolOutputLocKeys); rule.OutputLocationKeys = outputFileLocationsOfInterest; makeFile.RuleArray.Add(rule); var makeFilePath = MakeFileBuilder.GetMakeFilePathName(node); System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(makeFilePath)); Bam.Core.Log.DebugMessage("Makefile : '{0}'", makeFilePath); using (System.IO.TextWriter makeFileWriter = new System.IO.StreamWriter(makeFilePath)) { makeFile.Write(makeFileWriter); } success = true; var compilerTool = compilerInstance as Bam.Core.ITool; System.Collections.Generic.Dictionary<string, Bam.Core.StringArray> environment = null; if (compilerTool is Bam.Core.IToolEnvironmentVariables) { environment = (compilerTool as Bam.Core.IToolEnvironmentVariables).Variables((Bam.Core.BaseTarget)target); } var returnData = new MakeFileData(makeFilePath, makeFile.ExportedTargets, makeFile.ExportedVariables, environment); return returnData; }
ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { if (sender.Ignore) { return; } var collatedInterface = sender as ICollatedObject; if (sender.IsAnchor && null != collatedInterface.SourceModule) { // since all dependents are copied _beside_ their anchor, the anchor copy is a no-op return; } var copyFileTool = sender.Tool as CopyFileTool; string copySourcePath; string destinationDir; copyFileTool.convertPaths( sender, sender.SourcePath, collatedInterface.PublishingDirectory, out copySourcePath, out destinationDir); if (null == sender.PreExistingSourcePath) { Bam.Core.Log.DebugMessage("** {0}[{1}]:\t'{2}' -> '{3}'", collatedInterface.SourceModule.ToString(), collatedInterface.SourcePathKey.ToString(), copyFileTool.escapePath(copySourcePath), copyFileTool.escapePath(destinationDir)); } else { Bam.Core.Log.DebugMessage("** {0}: '{1}' -> '{2}'", sender, copyFileTool.escapePath(copySourcePath), copyFileTool.escapePath(destinationDir)); } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("IF NOT EXIST {0} MKDIR {0}", copyFileTool.escapePath(destinationDir))); var arePostBuildCommands = true; Bam.Core.Module sourceModule; if (null != collatedInterface.SourceModule) { sourceModule = collatedInterface.SourceModule; // check for runtime dependencies that won't have projects, use their anchor if (null == sourceModule.MetaData) { sourceModule = collatedInterface.Anchor.SourceModule; } } else { if (null != collatedInterface.Anchor) { // usually preexisting files that are published as part of an executable's distribution // in which case, their anchor is the executable (or a similar binary) sourceModule = collatedInterface.Anchor.SourceModule; } else { if (sender is CollatedPreExistingFile) { sourceModule = (sender as CollatedPreExistingFile).ParentOfCollationModule; // ensure a project exists, as this collation may be visited prior to // the source which invoked it var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution; solution.EnsureProjectExists(sourceModule); arePostBuildCommands = false; } else { throw new Bam.Core.Exception("No anchor set on '{0}' with source path '{1}'", sender.GetType().ToString(), sender.SourcePath); } } } var project = sourceModule.MetaData as VSSolutionBuilder.VSProject; var config = project.GetConfiguration(sourceModule); commands.Add(System.String.Format(@"{0} {1} {2} {3} {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), copyFileTool.escapePath(copySourcePath), copyFileTool.escapePath(destinationDir), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); if (config.Type != VSSolutionBuilder.VSProjectConfiguration.EType.Utility && arePostBuildCommands) { config.AddPostBuildCommands(commands); } else { config.AddPreBuildCommands(commands); } }
void ICollatedObjectPolicy.Collate( CollatedObject sender, Bam.Core.ExecutionContext context) { var sourcePath = sender.SourcePath; if (null == sender.Reference) { if ((null != sender.SourceModule.MetaData) || (sender.SourceModule is CollatedObject)) { // the main file is not copied anywhere, as we copy required files around it where VS wrote the main file // this is managed by the Collation class, querying the build mode for where publishing is relative to // ignore any subdirectory on this module // could also be a DebugSymbols or Stripped copy, in which case, ignore it return; } else { // the main reference file was a prebuilt - so create a new project to handle copying files var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution; var project = solution.EnsureProjectExists(sender.SourceModule); var config = project.GetConfiguration(sender.SourceModule); config.SetType(VSSolutionBuilder.VSProjectConfiguration.EType.Utility); config.SetOutputPath(sender.Macros["CopyDir"]); config.EnableIntermediatePath(); } } var commandLine = new Bam.Core.StringArray(); (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine); if (sender.SourceModule != null && sender.SourceModule.MetaData != null) { var destinationPath = sender.Macros["CopyDir"].Parse(); var project = sender.SourceModule.MetaData as VSSolutionBuilder.VSProject; var config = project.GetConfiguration(sender.SourceModule); var commands = new Bam.Core.StringArray(); commands.Add(System.String.Format("IF NOT EXIST {0} MKDIR {0}", destinationPath)); if (config.Type != VSSolutionBuilder.VSProjectConfiguration.EType.Utility) { commands.Add(System.String.Format(@"{0} {1} $(OutputPath)$(TargetFileName) {2} {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), destinationPath, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); config.AddPostBuildCommands(commands); } else { commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir).\ {3}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); config.AddPreBuildCommands(commands); } } else { var commands = new Bam.Core.StringArray(); if (sender is CollatedDirectory) { // Windows XCOPY requires the directory name to be added to the destination, while Posix cp does not commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir){3}\ {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), sender.CreateTokenizedString("$(0)/@ifnotempty($(CopiedFilename),$(CopiedFilename),@filename($(1)))", sender.SubDirectory, sourcePath).Parse(), CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } else { commands.Add(System.String.Format(@"{0} {1} {2} $(OutDir){3}\ {4}", CommandLineProcessor.Processor.StringifyTool(sender.Tool as Bam.Core.ICommandLineTool), commandLine.ToString(' '), sourcePath.ParseAndQuoteIfNecessary(), sender.SubDirectory, CommandLineProcessor.Processor.TerminatingArgs(sender.Tool as Bam.Core.ICommandLineTool))); } var project = sender.Reference.SourceModule.MetaData as VSSolutionBuilder.VSProject; var config = project.GetConfiguration(sender.Reference.SourceModule); if (config.Type != VSSolutionBuilder.VSProjectConfiguration.EType.Utility) { config.AddPostBuildCommands(commands); } else { config.AddPreBuildCommands(commands); } } }
IGeneratedSourcePolicy.GenerateSource( GeneratedSourceModule sender, Bam.Core.ExecutionContext context, Bam.Core.ICommandLineTool compiler, Bam.Core.TokenizedString generatedFilePath) { var meta = new MakeFileBuilder.MakeFileMeta(sender); var rule = meta.AddRule(); rule.AddTarget(generatedFilePath); var buildTool = (compiler as Bam.Core.Module).MetaData as MakeFileBuilder.MakeFileMeta; rule.AddOrderOnlyDependency(System.String.Format("$({0})", buildTool.Rules[0].Targets[0].VariableName)); var commandLineArgs = new Bam.Core.StringArray(); // TODO: change this to a configuration directory really commandLineArgs.Add(Bam.Core.TokenizedString.Create("$(buildroot)", null).Parse()); commandLineArgs.Add("Generated"); var command = new System.Text.StringBuilder(); command.AppendFormat("{0} {1} $^", compiler.Executable.ParseAndQuoteIfNecessary(), commandLineArgs.ToString(' ')); rule.AddShellCommand(command.ToString()); }