Build( XmlUtilities.XmlModule moduleToBuild, out bool success) { var node = moduleToBuild.OwningNode; var xmlLocation = moduleToBuild.Locations[XmlUtilities.XmlModule.OutputFile]; var xmlPath = xmlLocation.GetSinglePath(); if (null == xmlPath) { throw new Bam.Core.Exception("XML output path was not set"); } // dependency checking { var outputFiles = new Bam.Core.StringArray(); outputFiles.Add(xmlPath); if (!RequiresBuilding(outputFiles, new Bam.Core.StringArray())) { Bam.Core.Log.DebugMessage("'{0}' is up-to-date", node.UniqueModuleName); success = true; return(null); } } Bam.Core.Log.Info("Writing XML file '{0}'", xmlPath); // create all directories required var dirsToCreate = moduleToBuild.Locations.FilterByType(Bam.Core.ScaffoldLocation.ETypeHint.Directory, Bam.Core.Location.EExists.WillExist); foreach (var dir in dirsToCreate) { var dirPath = dir.GetSinglePath(); NativeBuilder.MakeDirectory(dirPath); } // serialize the XML to disk var settings = new System.Xml.XmlWriterSettings(); settings.CheckCharacters = true; settings.CloseOutput = true; settings.ConformanceLevel = System.Xml.ConformanceLevel.Auto; settings.Indent = true; settings.IndentChars = new string(' ', 4); settings.NewLineChars = "\n"; settings.NewLineHandling = System.Xml.NewLineHandling.None; settings.NewLineOnAttributes = false; settings.OmitXmlDeclaration = false; settings.Encoding = new System.Text.UTF8Encoding(false); // do not write BOM using (var xmlWriter = System.Xml.XmlWriter.Create(xmlPath, settings)) { moduleToBuild.Document.WriteTo(xmlWriter); xmlWriter.WriteWhitespace(settings.NewLineChars); } success = true; return(null); }
Build( XmlUtilities.XmlModule moduleToBuild, out bool success) { var isPlist = moduleToBuild is XmlUtilities.OSXPlistModule; var node = moduleToBuild.OwningNode; var locationMap = moduleToBuild.Locations; var outputDir = locationMap[XmlUtilities.OSXPlistModule.OutputDir]; var outputDirPath = outputDir.GetSingleRawPath(); if (!System.IO.Directory.Exists(outputDirPath)) { System.IO.Directory.CreateDirectory(outputDirPath); } var outputXMLLoc = locationMap[XmlUtilities.XmlModule.OutputFile]; var outputXMLPath = outputXMLLoc.GetSingleRawPath(); var targetNode = node.ExternalDependents[0]; var targetData = targetNode.Data as QMakeData; // write a script that can be invoked by QMake to generate the XML file var shellScriptLeafName = isPlist ? "writePList.py" : "writeXMLFile.py"; var shellScriptLoc = Bam.Core.FileLocation.Get(outputDir, shellScriptLeafName, Bam.Core.Location.EExists.WillExist); var shellScriptPath = shellScriptLoc.GetSingleRawPath(); XmlUtilities.XmlDocumentToPythonScript.Write(moduleToBuild.Document, shellScriptPath, outputXMLPath); if (null == targetData.CustomRules) { targetData.CustomRules = new Bam.Core.StringArray(); } targetData.CustomRules.Add("xmlTarget.target=" + outputXMLPath); targetData.CustomRules.Add("xmlTarget.depends=FORCE"); targetData.CustomRules.Add("xmlTarget.commands=python " + shellScriptPath); targetData.CustomRules.Add("PRE_TARGETDEPS+=" + outputXMLPath); targetData.CustomRules.Add("QMAKE_EXTRA_TARGETS+=xmlTarget"); // TODO: the Plist file is not always copied - find out why if (isPlist) { // TODO: I'd rather this be an explicit option if (null == targetData.CustomRules) { targetData.CustomRules = new Bam.Core.StringArray(); } targetData.CustomRules.Add("QMAKE_INFO_PLIST=" + outputXMLPath); } success = true; return(null); }
Build( XmlUtilities.XmlModule moduleToBuild, out bool success) { var isPlist = moduleToBuild is XmlUtilities.OSXPlistModule; var locationMap = moduleToBuild.Locations; var outputDir = locationMap[XmlUtilities.OSXPlistModule.OutputDir]; var outputDirPath = outputDir.GetSingleRawPath(); if (!System.IO.Directory.Exists(outputDirPath)) { System.IO.Directory.CreateDirectory(outputDirPath); } var xmlFileLoc = locationMap[XmlUtilities.XmlModule.OutputFile]; var xmlFilePath = xmlFileLoc.GetSingleRawPath(); // write a script that can be invoked by the MakeFile to generate the XML file var shellScriptLeafName = isPlist ? "writePList.py" : "writeXMLFile.py"; var shellScriptLoc = Bam.Core.FileLocation.Get(outputDir, shellScriptLeafName, Bam.Core.Location.EExists.WillExist); var shellScriptPath = shellScriptLoc.GetSingleRawPath(); XmlUtilities.XmlDocumentToPythonScript.Write(moduleToBuild.Document, shellScriptPath, xmlFilePath); var node = moduleToBuild.OwningNode; var makeFile = new MakeFile(node, this.topLevelMakeFilePath); var dirsToCreate = moduleToBuild.Locations.FilterByType(Bam.Core.ScaffoldLocation.ETypeHint.Directory, Bam.Core.Location.EExists.WillExist); var recipe = new Bam.Core.StringArray(); recipe.Add(System.String.Format("$(shell python {0})", shellScriptPath)); var rule = new MakeFileRule( moduleToBuild, XmlUtilities.XmlModule.OutputFile, node.UniqueModuleName, dirsToCreate, null, null, recipe); rule.OutputLocationKeys = new Bam.Core.Array <Bam.Core.LocationKey>(XmlUtilities.XmlModule.OutputFile); makeFile.RuleArray.Add(rule); var makeFilePath = MakeFileBuilder.GetMakeFilePathName(node); System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(makeFilePath)); using (var makeFileWriter = new System.IO.StreamWriter(makeFilePath)) { makeFile.Write(makeFileWriter); } var exportedTargets = makeFile.ExportedTargets; var exportedVariables = makeFile.ExportedVariables; var returnData = new MakeFileData(makeFilePath, exportedTargets, exportedVariables, null); success = true; return(returnData); }
Build( XmlUtilities.XmlModule moduleToBuild, out bool success) { var node = moduleToBuild.OwningNode; var targetNode = node.ExternalDependents[0]; var toProject = targetNode.Data as IProject; var configCollection = toProject.Configurations; var configurationName = configCollection.GetConfigurationNameForTarget((Bam.Core.BaseTarget)targetNode.Target); // TODO: not accurate var configuration = configCollection[configurationName]; var toolName = "VCPreBuildEventTool"; var vcPreBuildEventTool = configuration.GetTool(toolName); if (null == vcPreBuildEventTool) { vcPreBuildEventTool = new ProjectTool(toolName); configuration.AddToolIfMissing(vcPreBuildEventTool); } var commandLine = new System.Text.StringBuilder(); var locationMap = moduleToBuild.Locations; var outputDir = locationMap[XmlUtilities.XmlModule.OutputDir]; var outputDirPath = outputDir.GetSingleRawPath(); commandLine.AppendFormat("IF NOT EXIST {0} MKDIR {0}{1}", outputDirPath, System.Environment.NewLine); var outputFileLoc = locationMap[XmlUtilities.XmlModule.OutputFile]; var outputFilePath = outputFileLoc.GetSingleRawPath(); var content = XmlUtilities.XmlDocumentToStringBuilder.Write(moduleToBuild.Document); foreach (var line in content.ToString().Split('\n')) { commandLine.AppendFormat("ECHO {0} >> {1}{2}", line, outputFilePath, System.Environment.NewLine); } { string attributeName = null; if (VisualStudioProcessor.EVisualStudioTarget.VCPROJ == toProject.VSTarget) { attributeName = "CommandLine"; } else if (VisualStudioProcessor.EVisualStudioTarget.MSBUILD == toProject.VSTarget) { attributeName = "Command"; } lock (vcPreBuildEventTool) { if (vcPreBuildEventTool.HasAttribute(attributeName)) { var currentValue = vcPreBuildEventTool[attributeName]; currentValue += commandLine.ToString(); vcPreBuildEventTool[attributeName] = currentValue; } else { vcPreBuildEventTool.AddAttribute(attributeName, commandLine.ToString()); } } } success = true; return(null); }
Build( XmlUtilities.XmlModule moduleToBuild, out bool success) { // TODO: might have to implement PList specific Build functions var isPList = moduleToBuild is XmlUtilities.OSXPlistModule; var node = moduleToBuild.OwningNode; var targetNode = node.ExternalDependents[0]; var project = this.Workspace.GetProject(targetNode); var baseTarget = (Bam.Core.BaseTarget)targetNode.Target; var configuration = project.BuildConfigurations.Get(baseTarget.ConfigurationName('='), targetNode.ModuleName); var xmlFileLoc = moduleToBuild.Locations[XmlUtilities.XmlModule.OutputFile]; var xmlFilePath = xmlFileLoc.GetSingleRawPath(); // serialize the XML to memory var settings = new System.Xml.XmlWriterSettings(); settings.CheckCharacters = true; settings.CloseOutput = true; settings.ConformanceLevel = System.Xml.ConformanceLevel.Auto; settings.Indent = true; settings.IndentChars = new string(' ', 4); settings.NewLineChars = "\n"; settings.NewLineHandling = System.Xml.NewLineHandling.None; settings.NewLineOnAttributes = false; settings.OmitXmlDeclaration = false; settings.Encoding = new System.Text.UTF8Encoding(false); // do not write BOM var xmlString = new System.Text.StringBuilder(); using (var xmlWriter = System.Xml.XmlWriter.Create(xmlString, settings)) { moduleToBuild.Document.WriteTo(xmlWriter); xmlWriter.WriteWhitespace(settings.NewLineChars); } string shellScriptName; if (isPList) { shellScriptName = "Writing PList for " + targetNode.UniqueModuleName; } else { shellScriptName = "Writing XML file for " + targetNode.UniqueModuleName; } var writeXMLShellScriptBuildPhase = project.ShellScriptBuildPhases.Get(shellScriptName, node.ModuleName); writeXMLShellScriptBuildPhase.OutputPaths.Add(xmlFilePath); writeXMLShellScriptBuildPhase.ShellScriptLines.Add(System.String.Format("if [ \\\"${{CONFIGURATION}}\\\" = \\\"{0}\\\" ]; then", configuration.Name)); foreach (var line in xmlString.ToString().Split('\n')) { var escapedLine = line.Replace("\"", "\\\""); writeXMLShellScriptBuildPhase.ShellScriptLines.Add(System.String.Format("echo \\\"{0}\\\" >> $SCRIPT_OUTPUT_FILE_0", escapedLine)); } writeXMLShellScriptBuildPhase.ShellScriptLines.Add("fi"); if (isPList) { // because this is performed AFTER the application, we can directly add to the build phases var nativeTarget = targetNode.Data as PBXNativeTarget; nativeTarget.BuildPhases.Insert(0, writeXMLShellScriptBuildPhase); // add the Info.plist into the FileReferences var fileRef = project.FileReferences.Get(targetNode.ModuleName, PBXFileReference.EType.PList, xmlFilePath, project.RootUri); nativeTarget.Group.Children.AddUnique(fileRef); // add to the build configuration var baseTarget2 = (Bam.Core.BaseTarget)moduleToBuild.OwningNode.Target; var buildConfiguration = project.BuildConfigurations.Get(baseTarget2.ConfigurationName('='), targetNode.ModuleName); buildConfiguration.Options["INFOPLIST_FILE"].AddUnique(xmlFilePath); } success = true; return(null); }