public Makefile Deploy(AutotoolsContext ctx, SolutionItem entry, IProgressMonitor monitor) { generateAutotools = ctx.MakefileType == MakefileType.AutotoolsMakefile; monitor.BeginTask(GettextCatalog.GetString( "Creating {0} for Solution {1}", generateAutotools ? "Makefile.am" : "Makefile", entry.Name), 1); Makefile solutionMakefile = new Makefile(); StringBuilder solutionTop = new StringBuilder(); try { SolutionFolder solutionFolder = (SolutionFolder)entry; string targetDirectory = solutionFolder.BaseDirectory; StringBuilder subdirs = new StringBuilder(); subdirs.Append("#Warning: This is an automatically generated file, do not edit!\n"); if (!generateAutotools) { solutionTop.AppendFormat("top_srcdir={0}\n", FileService.AbsoluteToRelativePath( entry.BaseDirectory, ctx.TargetSolution.BaseDirectory)); solutionTop.Append("include $(top_srcdir)/config.make\n"); solutionTop.Append("include $(top_srcdir)/Makefile.include\n"); solutionTop.Append("include $(top_srcdir)/rules.make\n\n"); solutionTop.Append("#include $(top_srcdir)/custom-hooks.make\n\n"); } ArrayList children = new ArrayList(); foreach (SolutionConfiguration config in solutionFolder.ParentSolution.Configurations) { if (!ctx.IsSupportedConfiguration(config.Id)) { continue; } if (generateAutotools) { subdirs.AppendFormat("if {0}\n", "ENABLE_" + ctx.EscapeAndUpperConfigName(config.Id)); } else { subdirs.AppendFormat("ifeq ($(CONFIG),{0})\n", ctx.EscapeAndUpperConfigName(config.Id)); } subdirs.Append(" SUBDIRS = "); foreach (SolutionItem ce in CalculateSubDirOrder(ctx, solutionFolder, config)) { string baseDirectory; if (!(ce is SolutionEntityItem) && !(ce is SolutionFolder)) { continue; } // Ignore projects which can't be deployed IMakefileHandler handler = AutotoolsContext.GetMakefileHandler(ce, ctx.MakefileType); if (handler == null) { continue; } baseDirectory = ce.BaseDirectory; if (solutionFolder.BaseDirectory == baseDirectory) { subdirs.Append(" . "); } else { if (!baseDirectory.StartsWith(solutionFolder.BaseDirectory)) { throw new Exception(GettextCatalog.GetString( "Child projects must be in sub-directories of their parent")); } // add the subdirectory to the list string path = FileService.AbsoluteToRelativePath(targetDirectory, baseDirectory); if (path.StartsWith("." + Path.DirectorySeparatorChar)) { path = path.Substring(2); } AutotoolsContext.CheckSpaces(path); subdirs.Append(" "); subdirs.Append(AutotoolsContext.EscapeStringForAutomake(path)); } if (!children.Contains(ce)) { children.Add(ce); } } subdirs.Append("\nendif\n"); } solutionTop.Append(subdirs.ToString()); string includedProject = null; // deploy recursively foreach (SolutionItem ce in children) { IMakefileHandler handler = AutotoolsContext.GetMakefileHandler(ce, ctx.MakefileType); Makefile makefile; string outpath; if (handler != null && handler.CanDeploy(ce, ctx.MakefileType)) { ctx.RegisterBuiltProject(ce); makefile = handler.Deploy(ctx, ce, monitor); if (targetDirectory == ce.BaseDirectory) { if (includedProject != null) { throw new Exception(GettextCatalog.GetString( "More than 1 project in the same directory as the top-level solution is not supported.")); } // project is in the solution directory string projectMakefileName = ce.Name + ".make"; includedProject = String.Format("include {0}", projectMakefileName); outpath = Path.Combine(targetDirectory, projectMakefileName); ctx.AddGeneratedFile(outpath); if (!generateAutotools) { solutionMakefile.SetVariable("EXTRA_DIST", projectMakefileName); } } else { makefile.AppendToVariable("EXTRA_DIST", generateAutotools ? String.Empty : "Makefile"); outpath = Path.Combine(ce.BaseDirectory, "Makefile"); if (generateAutotools) { ctx.AddAutoconfFile(outpath); outpath = outpath + ".am"; } else { makefile.Append("install: install-local\nuninstall: uninstall-local\nclean: clean-local\n"); if (ce is SolutionFolder) { //non TargetCombine makefile.Append("dist-local: dist-local-recursive\n"); } else { makefile.Append("include $(top_srcdir)/rules.make\n"); } } ctx.AddGeneratedFile(outpath); } StreamWriter writer = new StreamWriter(outpath); makefile.Write(writer); writer.Close(); } else { monitor.Log.WriteLine("Project '{0}' skipped.", ce.Name); } } if (includedProject != null) { solutionTop.Append(GettextCatalog.GetString("\n# Include project specific makefile\n")); solutionTop.Append(includedProject); } if (generateAutotools) { solutionMakefile.Append(solutionTop.ToString()); } else { TemplateEngine templateEngine = new TemplateEngine(); templateEngine.Variables ["MAKEFILE_SOLUTION_TOP"] = solutionTop.ToString(); Stream stream = ctx.GetTemplateStream("Makefile.solution.template"); StreamReader reader = new StreamReader(stream); StringWriter sw = new StringWriter(); templateEngine.Process(reader, sw); reader.Close(); solutionMakefile.Append(sw.ToString()); if (solutionFolder.IsRoot) { // Emit dist and distcheck targets only for TargetCombine reader = new StreamReader(Path.Combine(ctx.TemplateDir, "make-dist.targets")); solutionMakefile.Append(reader.ReadToEnd()); reader.Close(); } } monitor.Step(1); } finally { monitor.EndTask(); } return(solutionMakefile); }
public bool GenerateFiles(DeployContext ctx, Solution solution, string defaultConf, IProgressMonitor monitor) { string filesString = generateAutotools ? "Autotools files" : "Makefiles"; monitor.BeginTask(GettextCatalog.GetString("Generating {0} for Solution {1}", filesString, solution.Name), 1); try { solution_dir = Path.GetDirectoryName(solution.FileName); string[] configs = new string [solution.Configurations.Count]; for (int ii = 0; ii < configs.Length; ii++) { configs [ii] = solution.Configurations[ii].Id; } MakefileType mt = generateAutotools ? MakefileType.AutotoolsMakefile : MakefileType.SimpleMakefile; context = new AutotoolsContext(ctx, solution_dir, configs, mt); context.TargetSolution = solution; context.Switches = switchs; IMakefileHandler handler = AutotoolsContext.GetMakefileHandler(solution.RootFolder, mt); if (handler == null) { throw new Exception(GettextCatalog.GetString("MonoDevelop does not currently support generating {0} for one (or more) child projects.", filesString)); } solution_name = solution.Name; solution_version = AutotoolsContext.EscapeStringForAutoconf(solution.Version, true); if (string.IsNullOrEmpty(solution_version)) { solution_version = "0.1"; } Makefile makefile = handler.Deploy(context, solution.RootFolder, monitor); string path = Path.Combine(solution_dir, "Makefile"); if (generateAutotools) { context.AddAutoconfFile(path); CreateAutoGenDotSH(context, monitor); CreateConfigureDotAC(solution, defaultConf, monitor, context); CreateMacros(); } else { CreateConfigureScript(solution, defaultConf, context, monitor); monitor.Log.WriteLine(GettextCatalog.GetString("Creating rules.make")); string rules_make_path = Path.Combine(solution_dir, "rules.make"); File.Copy(Path.Combine(context.TemplateDir, "rules.make"), rules_make_path, true); context.AddGeneratedFile(rules_make_path); } CreateMakefileInclude(context, monitor); AddTopLevelMakefileVars(makefile, monitor); if (generateAutotools) { path = path + ".am"; } StreamWriter writer = new StreamWriter(path); makefile.Write(writer); writer.Close(); context.AddGeneratedFile(path); monitor.ReportSuccess(GettextCatalog.GetString("{0} were successfully generated.", filesString)); monitor.Step(1); } catch (Exception e) { monitor.ReportError(GettextCatalog.GetString("{0} could not be generated: ", filesString), e); LoggingService.LogError(GettextCatalog.GetString("{0} could not be generated: ", filesString), e); DeleteGeneratedFiles(context); return(false); } finally { monitor.EndTask(); } return(true); }