/// <summary> /// Deploys a makefile to build the default configuration. /// </summary> /// <remarks> /// TODO: Make configuration-based targets as advertised. /// </remarks> public Makefile Deploy (AutotoolsContext ctx, MonoDevelop.Projects.SolutionItem entry, MonoDevelop.Core.IProgressMonitor monitor) { Makefile mkfile = new Makefile (); ValaProject project = (ValaProject) entry; ValaProjectConfiguration conf = (ValaProjectConfiguration)project.DefaultConfiguration; StringBuilder files = new StringBuilder (); foreach (ProjectFile t in project.Files) { if(BuildAction.Compile == t.BuildAction) { files.Append ("\\\n\t" + FileService.AbsoluteToRelativePath(project.BaseDirectory, t.FilePath)); } } string dir = ctx.DeployContext.GetResolvedPath (TargetDirectory.ProgramFiles, FileService.AbsoluteToRelativePath(conf.OutputDirectory, ctx.TargetSolution.BaseDirectory)); dir = dir.Replace ("@prefix@", "$(prefix)"); dir = dir.Replace ("@PACKAGE@", "$(PACKAGE)"); TemplateEngine templateEngine = new TemplateEngine (); templateEngine.Variables ["TOP_SRCDIR"] = FileService.AbsoluteToRelativePath (project.BaseDirectory, ctx.TargetSolution.BaseDirectory); templateEngine.Variables ["FILES"] = files.ToString (); templateEngine.Variables ["BUILD_DIR"] = "."; templateEngine.Variables ["INSTALL_DIR"] = "$(DESTDIR)" + dir; templateEngine.Variables ["ALL_TARGET"] = string.Format("all-{0}", conf.Name); templateEngine.Variables ["VFLAGS"] = string.Format("{0} {1}", ValaCompiler.GetCompilerFlags(conf), ValaCompiler.GeneratePkgCompilerArgs(project.Packages)); templateEngine.Variables ["VTARGET"] = conf.CompiledOutputName; StringWriter sw = new StringWriter (); string mt; if (ctx.MakefileType == MakefileType.AutotoolsMakefile) mt = "Makefile.am.template"; else mt = "Makefile.template"; using (Stream stream = GetType().Assembly.GetManifestResourceStream (mt)) { StreamReader reader = new StreamReader (stream); templateEngine.Process (reader, sw); reader.Close (); } mkfile.Append (sw.ToString ()); return mkfile; }
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 Makefile Deploy (AutotoolsContext ctx, SolutionFolderItem entry, ProgressMonitor 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 (SolutionFolderItem ce in CalculateSubDirOrder (ctx, solutionFolder, config)) { string baseDirectory; if (!(ce is SolutionItem) && !(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 (SolutionFolderItem 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 Makefile Deploy(AutotoolsContext ctx, SolutionFolderItem entry, ProgressMonitor monitor) { generateAutotools = ctx.MakefileType == MakefileType.AutotoolsMakefile; monitor.BeginTask(GettextCatalog.GetString( "Creating {0} for Project {1}", generateAutotools ? "Makefile.am" : "Makefile", entry.Name), 1); Makefile makefile = new Makefile(); try { if (!CanDeploy(entry, generateAutotools ? MakefileType.AutotoolsMakefile : MakefileType.SimpleMakefile)) { throw new Exception(GettextCatalog.GetString("Not a deployable project.")); } Project project = entry as Project; TemplateEngine templateEngine = new TemplateEngine(); ISimpleAutotoolsSetup setup = FindSetupForProject(project); // Handle files to be deployed deployDirs = new Dictionary <string, StringBuilder> (); deployFileVars = new Dictionary <string, string> (); builtFiles = new List <string> (); deployFileCopyVars = new StringBuilder(); deployFileCopyTargets = new StringBuilder(); //used only for simple makefile generation templateFilesTargets = null; installTarget = null; installDeps = null; installDirs = null; uninstallTarget = null; // handle configuration specific variables conf_vars = new StringBuilder(); // grab all project files files = new StringBuilder(); res_files = new StringBuilder(); extras = new StringBuilder(); datafiles = new StringBuilder(); Set <string> extraFiles = new Set <string> (); string includes = String.Empty; string references, dllReferences; DotNetProject netProject = project as DotNetProject; ProcessProjectReferences(netProject, out references, out dllReferences, ctx); templateEngine.Variables["REFERENCES"] = references; templateEngine.Variables["DLL_REFERENCES"] = dllReferences; templateEngine.Variables["WARNING"] = "Warning: This is an automatically generated file, do not edit!"; if (entry is DotNetProject dotnetProject) { templateEngine.Variables ["RESGEN"] = "resgen"; } string pfpath = null; foreach (ProjectFile projectFile in project.Files) { pfpath = FileService.NormalizeRelativePath(projectFile.FilePath.ToRelative(project.BaseDirectory)); switch (projectFile.BuildAction) { case BuildAction.Compile: if (projectFile.Subtype != Subtype.Code) { continue; } files.AppendFormat("\\\n\t{0} ", MakefileData.ToMakefilePath(pfpath)); break; case BuildAction.Content: case BuildAction.None: extraFiles.Add(MakefileData.ToMakefilePath(pfpath)); break; case BuildAction.EmbeddedResource: if (!projectFile.FilePath.IsChildPathOf(ctx.BaseDirectory)) { // file is not within directory hierarchy, copy it in string rdir = Path.Combine(Path.GetDirectoryName(project.FileName), resourcedir); if (!Directory.Exists(rdir)) { Directory.CreateDirectory(rdir); } string newPath = Path.Combine(rdir, Path.GetFileName(projectFile.FilePath)); FileService.CopyFile(projectFile.FilePath, newPath); pfpath = project.GetRelativeChildPath(newPath); pfpath = FileService.NormalizeRelativePath(pfpath); } if (!String.IsNullOrEmpty(projectFile.ResourceId) && projectFile.ResourceId != Path.GetFileName(pfpath)) { res_files.AppendFormat("\\\n\t{0},{1} ", MakefileData.ToMakefilePath(pfpath), MakefileData.EscapeString(projectFile.ResourceId)); } else { res_files.AppendFormat("\\\n\t{0} ", MakefileData.ToMakefilePath(pfpath)); } break; case "FileCopy": datafiles.AppendFormat("\\\n\t{0} ", MakefileData.ToMakefilePath(pfpath)); break; } } if (!generateAutotools) { templateFilesTargets = new StringBuilder(); installTarget = new StringBuilder(); uninstallTarget = new StringBuilder(); installDeps = new StringBuilder(); installDirs = new List <string> (); customCommands = new StringBuilder(); string programFilesDir = ctx.DeployContext.GetDirectory(TargetDirectory.ProgramFiles); //FIXME:temp programFilesDir = TranslateDir(programFilesDir); installDirs.Add(programFilesDir); installTarget.Append("\tmake pre-install-local-hook prefix=$(prefix)\n"); installTarget.Append("\tmake install-satellite-assemblies prefix=$(prefix)\n"); installTarget.AppendFormat("\tmkdir -p '$(DESTDIR){0}'\n", programFilesDir); installTarget.AppendFormat("\t$(call cp,$(ASSEMBLY),$(DESTDIR){0})\n", programFilesDir); installTarget.AppendFormat("\t$(call cp,$(ASSEMBLY_MDB),$(DESTDIR){0})\n", programFilesDir); //remove dir? uninstallTarget.Append("\tmake pre-uninstall-local-hook prefix=$(prefix)\n"); uninstallTarget.Append("\tmake uninstall-satellite-assemblies prefix=$(prefix)\n"); uninstallTarget.AppendFormat("\t$(call rm,$(ASSEMBLY),$(DESTDIR){0})\n", programFilesDir); uninstallTarget.AppendFormat("\t$(call rm,$(ASSEMBLY_MDB),$(DESTDIR){0})\n", programFilesDir); installDeps.Append(" $(ASSEMBLY) $(ASSEMBLY_MDB)"); conf_vars.AppendFormat("srcdir=.\n"); conf_vars.AppendFormat("top_srcdir={0}\n\n", FileService.AbsoluteToRelativePath(project.BaseDirectory, ctx.TargetSolution.BaseDirectory)); conf_vars.AppendFormat("include $(top_srcdir)/config.make\n\n"); // Don't emit for top level project makefile(eg. pdn.make), as it would be // included by top level solution makefile if (ctx.TargetSolution.BaseDirectory != project.BaseDirectory) { string customhooks = Path.Combine(project.BaseDirectory, "custom-hooks.make"); bool include = File.Exists(customhooks); includes = "include $(top_srcdir)/Makefile.include\n"; includes += String.Format("{0}include $(srcdir)/custom-hooks.make\n\n", include ? "" : "#"); if (include) { makefile.SetVariable("EXTRA_DIST", "$(srcdir)/custom-hooks.make"); } } } bool buildEnabled; List <ConfigSection> configSections = new List <ConfigSection> (); allDeployVars = new Dictionary <string, DeployFileData> (); foreach (SolutionConfiguration combineConfig in ctx.TargetSolution.Configurations) { DotNetProjectConfiguration config = GetProjectConfig(combineConfig.Id, project, out buildEnabled) as DotNetProjectConfiguration; if (config == null) { continue; } ConfigSection configSection = new ConfigSection(combineConfig.Id); string assembly = MakefileData.GetUnixPath(project.GetRelativeChildPath(config.CompiledOutputName)); configSection.BuildVariablesBuilder.AppendFormat("ASSEMBLY_COMPILER_COMMAND = {0}\n", setup.GetCompilerCommand(project, config.Id)); configSection.BuildVariablesBuilder.AppendFormat("ASSEMBLY_COMPILER_FLAGS = {0}\n", setup.GetCompilerFlags(project, config.Id)); // add check for compiler command in configure.ac ctx.AddCommandCheck(setup.GetCompilerCommand(project, config.Id)); configSection.BuildVariablesBuilder.AppendFormat("ASSEMBLY = {0}\n", AutotoolsContext.EscapeStringForAutomake(assembly)); configSection.BuildVariablesBuilder.AppendFormat("ASSEMBLY_MDB = {0}\n", config.DebugSymbols ? "$(ASSEMBLY).mdb" : String.Empty); string target; switch (config.CompileTarget) { case CompileTarget.Exe: target = "exe"; break; case CompileTarget.Library: target = "library"; break; case CompileTarget.WinExe: target = "winexe"; break; case CompileTarget.Module: target = "module"; break; default: throw new Exception(GettextCatalog.GetString("Unknown target {0}", config.CompileTarget)); } configSection.BuildVariablesBuilder.AppendFormat("COMPILE_TARGET = {0}\n", target); // for project references, we need a ref to the dll for the current configuration StringWriter projectReferences = new StringWriter(); string pref = null; foreach (ProjectReference reference in netProject.References) { if (reference.ReferenceType != ReferenceType.Project) { continue; } Project refp = reference.ResolveProject(ctx.TargetSolution); if (refp == null) { throw new Exception(GettextCatalog.GetString("Couldn't find referenced project '{0}'", reference.Reference)); } if (!(refp is DotNetProject)) { continue; } DotNetProjectConfiguration dnpc = GetProjectConfig(combineConfig.Id, refp, out buildEnabled) as DotNetProjectConfiguration; if (dnpc == null) { throw new Exception(GettextCatalog.GetString ("Could not add reference to project '{0}'", refp.Name)); } projectReferences.WriteLine(" \\"); projectReferences.Write("\t"); pref = project.GetRelativeChildPath(dnpc.CompiledOutputName); projectReferences.Write(MakefileData.ToMakefilePath(pref)); } configSection.BuildVariablesBuilder.AppendFormat("PROJECT_REFERENCES = {0}\n", projectReferences.ToString()); string buildDir = project.GetRelativeChildPath(config.OutputDirectory); configSection.BuildVariablesBuilder.AppendFormat("BUILD_DIR = {0}\n", MakefileData.ToMakefilePath(buildDir)); // Register files built by this configuration. // Built files won't be distributed. foreach (string bfile in builtFiles) { ctx.AddBuiltFile(Path.Combine(config.OutputDirectory, bfile)); } DeployFileCollection deployFiles = DeployService.GetDeployFiles( ctx.DeployContext, new SolutionFolderItem[] { project }, config.Selector); ProcessDeployFilesForConfig(deployFiles, project, configSection, ctx, config); configSections.Add(configSection); if (!generateAutotools) { EmitCustomCommandTargets(config.CustomCommands, project, customCommands, combineConfig.Id, new CustomCommandType [] { CustomCommandType.BeforeBuild, CustomCommandType.AfterBuild, CustomCommandType.BeforeClean, CustomCommandType.AfterClean }, monitor); } else { if (config.CustomCommands.Count > 0) { monitor.ReportWarning(GettextCatalog.GetString("Custom commands are not supported for autotools based makefiles. Ignoring.")); } } // Register files generated by the compiler ctx.AddBuiltFile(project.GetOutputFileName(combineConfig.Selector)); if (config.DebugSymbols) { ctx.AddBuiltFile(project.GetOutputFileName(combineConfig.Selector) + ".mdb"); } if (config.SignAssembly) { string spath = project.GetRelativeChildPath(config.AssemblyKeyFile); spath = FileService.NormalizeRelativePath(spath); extraFiles.Add(MakefileData.ToMakefilePath(spath)); } if (buildEnabled && pkgs.Count > 0) { ctx.AddRequiredPackages(combineConfig.Id, pkgs); } } foreach (string ef in extraFiles) { extras.AppendFormat("\\\n\t{0} ", ef); } Dictionary <string, DeployFileData> commonDeployVars = new Dictionary <string, DeployFileData> (allDeployVars); foreach (ConfigSection configSection in configSections) { List <string> toRemove = new List <string> (); foreach (KeyValuePair <string, DeployFileData> pair in commonDeployVars) { if (!configSection.DeployFileVars.ContainsKey(pair.Key)) { toRemove.Add(pair.Key); } } foreach (string s in toRemove) { commonDeployVars.Remove(s); } } //emit the config sections here.. to conf_vars foreach (ConfigSection configSection in configSections) { conf_vars.AppendFormat(generateAutotools ? "if ENABLE_{0}\n" : "ifeq ($(CONFIG),{0})\n", ctx.EscapeAndUpperConfigName(configSection.Name)); conf_vars.Append(configSection.BuildVariablesBuilder.ToString()); conf_vars.Append("\n"); if (ctx.Switches != null) { foreach (Switch s in ctx.Switches) { conf_vars.AppendLine(string.Format(@"if ENABLE_{0} ASSEMBLY_COMPILER_FLAGS += -define:{1} endif", s.SwitchName.Replace('-', '_').ToUpperInvariant(), s.Define)); } } foreach (KeyValuePair <string, DeployFileData> pair in allDeployVars) { string targetDeployVar = pair.Key; if (pair.Value.File.ContainsPathReferences) { //Template files are not handled per-config continue; } if (configSection.DeployFileVars.ContainsKey(targetDeployVar)) { //use the dfile from the config section DeployFile dfile = configSection.DeployFileVars [targetDeployVar]; string fname = MakefileData.ToMakefilePath( FileService.AbsoluteToRelativePath( Path.GetFullPath(project.BaseDirectory), Path.GetFullPath(dfile.SourcePath))); conf_vars.AppendFormat("{0}_SOURCE={1}\n", targetDeployVar, fname); if (!commonDeployVars.ContainsKey(targetDeployVar)) { //FOO_DLL=$(BUILD_DIR)/foo.dll conf_vars.AppendFormat("{0}=$(BUILD_DIR)/{1}\n", targetDeployVar, MakefileData.ToMakefilePath(dfile.RelativeTargetPath)); } } else { // not common and not part of @configSection conf_vars.AppendFormat("{0}=\n", pair.Key); } } conf_vars.Append("\nendif\n\n"); } conf_vars.AppendFormat("AL=al\n"); conf_vars.AppendFormat("SATELLITE_ASSEMBLY_NAME=$(notdir $(basename $(ASSEMBLY))).resources.dll\n"); foreach (KeyValuePair <string, DeployFileData> pair in allDeployVars) { HandleDeployFile(pair.Value, pair.Key, project, ctx); if (commonDeployVars.ContainsKey(pair.Key)) { //FOO_DLL=$(BUILD_DIR)/foo.dll deployFileCopyVars.AppendFormat("{0} = $(BUILD_DIR)/{1}\n", pair.Key, MakefileData.ToMakefilePath(pair.Value.File.RelativeTargetPath)); } } conf_vars.Append('\n'); StringBuilder vars = new StringBuilder(); foreach (KeyValuePair <string, StringBuilder> pair in deployDirs) { //PROGRAM_FILES= .. etc conf_vars.AppendFormat("{0} = {1} \n\n", pair.Key, pair.Value.ToString()); //Build list of deploy dir variables vars.AppendFormat("$({0}) ", pair.Key); } if (!generateAutotools) { installTarget.Insert(0, String.Format("install-local:{0}\n", installDeps.ToString())); installTarget.Append("\tmake post-install-local-hook prefix=$(prefix)\n"); uninstallTarget.Insert(0, String.Format("uninstall-local:{0}\n", installDeps.ToString())); uninstallTarget.Append("\tmake post-uninstall-local-hook prefix=$(prefix)\n"); } if (!generateAutotools && customCommands.Length > 0) { customCommands.Insert(0, "# Targets for Custom commands\n"); } templateEngine.Variables["CONFIG_VARS"] = conf_vars.ToString(); templateEngine.Variables["DEPLOY_FILE_VARS"] = vars.ToString(); templateEngine.Variables["COPY_DEPLOY_FILES_VARS"] = deployFileCopyVars.ToString(); templateEngine.Variables["COPY_DEPLOY_FILES_TARGETS"] = deployFileCopyTargets.ToString(); templateEngine.Variables["ALL_TARGET"] = (ctx.TargetSolution.BaseDirectory == project.BaseDirectory) ? "all-local" : "all"; templateEngine.Variables["INCLUDES"] = includes; templateEngine.Variables["FILES"] = files.ToString(); templateEngine.Variables["RESOURCES"] = res_files.ToString(); templateEngine.Variables["EXTRAS"] = extras.ToString(); templateEngine.Variables["DATA_FILES"] = datafiles.ToString(); templateEngine.Variables["CLEANFILES"] = vars.ToString(); if (!generateAutotools) { templateEngine.Variables["TEMPLATE_FILES_TARGETS"] = templateFilesTargets.ToString(); templateEngine.Variables["INSTALL_TARGET"] = installTarget.ToString(); templateEngine.Variables["UNINSTALL_TARGET"] = uninstallTarget.ToString(); templateEngine.Variables["CUSTOM_COMMAND_TARGETS"] = customCommands.ToString(); } // Create project specific makefile Stream stream = ctx.GetTemplateStream( generateAutotools ? "Makefile.am.project.template" : "Makefile.noauto.project.template"); StreamReader reader = new StreamReader(stream); string txt = templateEngine.Process(reader); reader.Close(); makefile.Append(txt); monitor.Step(1); } finally { monitor.EndTask(); } return(makefile); }
public Makefile Deploy (AutotoolsContext ctx, SolutionItem entry, IProgressMonitor monitor) { generateAutotools = ctx.MakefileType == MakefileType.AutotoolsMakefile; monitor.BeginTask ( GettextCatalog.GetString ( "Creating {0} for Project {1}", generateAutotools ? "Makefile.am" : "Makefile", entry.Name), 1 ); Makefile makefile = new Makefile (); try { if ( !CanDeploy (entry, generateAutotools ? MakefileType.AutotoolsMakefile : MakefileType.SimpleMakefile) ) throw new Exception ( GettextCatalog.GetString ("Not a deployable project.") ); Project project = entry as Project; TemplateEngine templateEngine = new TemplateEngine(); ISimpleAutotoolsSetup setup = FindSetupForProject ( project ); // Handle files to be deployed deployDirs = new Dictionary<string, StringBuilder> (); deployFileVars = new Dictionary<string, string> (); builtFiles = new List<string> (); deployFileCopyVars = new StringBuilder (); deployFileCopyTargets = new StringBuilder (); //used only for simple makefile generation templateFilesTargets = null; installTarget = null; installDeps = null; installDirs = null; uninstallTarget = null; // handle configuration specific variables conf_vars = new StringBuilder (); // grab all project files files = new StringBuilder (); res_files = new StringBuilder (); extras = new StringBuilder (); datafiles = new StringBuilder (); Set<string> extraFiles = new Set<string> (); string includes = String.Empty; string references, dllReferences; DotNetProject netProject = project as DotNetProject; ProcessProjectReferences (netProject, out references, out dllReferences, ctx); templateEngine.Variables["REFERENCES"] = references; templateEngine.Variables["DLL_REFERENCES"] = dllReferences; templateEngine.Variables["WARNING"] = "Warning: This is an automatically generated file, do not edit!"; DotNetProject dotnetProject = entry as DotNetProject; if (dotnetProject != null) { string resgen = "resgen"; if (System.Environment.Version.Major >= 2) { switch (dotnetProject.TargetFramework.ClrVersion) { case ClrVersion.Net_1_1: resgen = "resgen1"; break; default: resgen = "resgen2"; break; } } templateEngine.Variables ["RESGEN"] = resgen; } string pfpath = null; foreach (ProjectFile projectFile in project.Files) { pfpath = FileService.NormalizeRelativePath (projectFile.FilePath.ToRelative (project.BaseDirectory)); switch ( projectFile.BuildAction ) { case BuildAction.Compile: if ( projectFile.Subtype != Subtype.Code ) continue; files.AppendFormat ( "\\\n\t{0} ", MakefileData.ToMakefilePath (pfpath)); break; case BuildAction.Content: case BuildAction.None: extraFiles.Add (MakefileData.ToMakefilePath (pfpath)); break; case BuildAction.EmbeddedResource: if ( !projectFile.FilePath.IsChildPathOf ( ctx.BaseDirectory ) ) { // file is not within directory hierarchy, copy it in string rdir = Path.Combine (Path.GetDirectoryName (project.FileName), resourcedir); if ( !Directory.Exists ( rdir ) ) Directory.CreateDirectory ( rdir ); string newPath = Path.Combine (rdir, Path.GetFileName ( projectFile.FilePath )); FileService.CopyFile ( projectFile.FilePath, newPath ) ; pfpath = project.GetRelativeChildPath (newPath); pfpath = FileService.NormalizeRelativePath (pfpath); } if (!String.IsNullOrEmpty (projectFile.ResourceId) && projectFile.ResourceId != Path.GetFileName (pfpath)) res_files.AppendFormat ("\\\n\t{0},{1} ", MakefileData.ToMakefilePath (pfpath), MakefileData.EscapeString (projectFile.ResourceId)); else res_files.AppendFormat ("\\\n\t{0} ", MakefileData.ToMakefilePath (pfpath)); break; case "FileCopy": datafiles.AppendFormat ("\\\n\t{0} ", MakefileData.ToMakefilePath (pfpath)); break; } } if (!generateAutotools) { templateFilesTargets = new StringBuilder (); installTarget = new StringBuilder (); uninstallTarget = new StringBuilder (); installDeps = new StringBuilder (); installDirs = new List<string> (); customCommands = new StringBuilder (); string programFilesDir = ctx.DeployContext.GetDirectory (TargetDirectory.ProgramFiles); //FIXME:temp programFilesDir = TranslateDir (programFilesDir); installDirs.Add (programFilesDir); installTarget.Append ("\tmake pre-install-local-hook prefix=$(prefix)\n"); installTarget.Append ("\tmake install-satellite-assemblies prefix=$(prefix)\n"); installTarget.AppendFormat ("\tmkdir -p '$(DESTDIR){0}'\n", programFilesDir); installTarget.AppendFormat ("\t$(call cp,$(ASSEMBLY),$(DESTDIR){0})\n", programFilesDir); installTarget.AppendFormat ("\t$(call cp,$(ASSEMBLY_MDB),$(DESTDIR){0})\n", programFilesDir); //remove dir? uninstallTarget.Append ("\tmake pre-uninstall-local-hook prefix=$(prefix)\n"); uninstallTarget.Append ("\tmake uninstall-satellite-assemblies prefix=$(prefix)\n"); uninstallTarget.AppendFormat ("\t$(call rm,$(ASSEMBLY),$(DESTDIR){0})\n", programFilesDir); uninstallTarget.AppendFormat ("\t$(call rm,$(ASSEMBLY_MDB),$(DESTDIR){0})\n", programFilesDir); installDeps.Append (" $(ASSEMBLY) $(ASSEMBLY_MDB)"); conf_vars.AppendFormat ("srcdir=.\n"); conf_vars.AppendFormat ("top_srcdir={0}\n\n", FileService.AbsoluteToRelativePath (project.BaseDirectory, ctx.TargetSolution.BaseDirectory)); conf_vars.AppendFormat ("include $(top_srcdir)/config.make\n\n"); // Don't emit for top level project makefile(eg. pdn.make), as it would be // included by top level solution makefile if (ctx.TargetSolution.BaseDirectory != project.BaseDirectory){ string customhooks = Path.Combine (project.BaseDirectory, "custom-hooks.make"); bool include = File.Exists (customhooks); includes = "include $(top_srcdir)/Makefile.include\n"; includes += String.Format ("{0}include $(srcdir)/custom-hooks.make\n\n", include ? "" : "#"); if (include) makefile.SetVariable ("EXTRA_DIST", "$(srcdir)/custom-hooks.make"); } } bool buildEnabled; List<ConfigSection> configSections = new List<ConfigSection> (); allDeployVars = new Dictionary<string, DeployFileData> (); foreach (SolutionConfiguration combineConfig in ctx.TargetSolution.Configurations) { DotNetProjectConfiguration config = GetProjectConfig (combineConfig.Id, project, out buildEnabled) as DotNetProjectConfiguration; if (config == null) continue; ConfigSection configSection = new ConfigSection (combineConfig.Id); string assembly = MakefileData.GetUnixPath (project.GetRelativeChildPath (config.CompiledOutputName)); configSection.BuildVariablesBuilder.AppendFormat ("ASSEMBLY_COMPILER_COMMAND = {0}\n", setup.GetCompilerCommand ( project, config.Id ) ); configSection.BuildVariablesBuilder.AppendFormat ("ASSEMBLY_COMPILER_FLAGS = {0}\n", setup.GetCompilerFlags ( project, config.Id ) ); // add check for compiler command in configure.ac ctx.AddCommandCheck ( setup.GetCompilerCommand ( project, config.Id ) ); configSection.BuildVariablesBuilder.AppendFormat ("ASSEMBLY = {0}\n", AutotoolsContext.EscapeStringForAutomake (assembly)); configSection.BuildVariablesBuilder.AppendFormat ("ASSEMBLY_MDB = {0}\n", config.DebugMode ? "$(ASSEMBLY).mdb" : String.Empty); string target; switch (config.CompileTarget) { case CompileTarget.Exe: target = "exe"; break; case CompileTarget.Library: target = "library"; break; case CompileTarget.WinExe: target = "winexe"; break; case CompileTarget.Module: target = "module"; break; default: throw new Exception( GettextCatalog.GetString ("Unknown target {0}", config.CompileTarget ) ); } configSection.BuildVariablesBuilder.AppendFormat ( "COMPILE_TARGET = {0}\n", target ); // for project references, we need a ref to the dll for the current configuration StringWriter projectReferences = new StringWriter(); string pref = null; foreach (ProjectReference reference in netProject.References) { if (reference.ReferenceType != ReferenceType.Project) continue; Project refp = GetProjectFromName (reference.Reference, ctx.TargetSolution); if (!(refp is DotNetProject)) continue; DotNetProjectConfiguration dnpc = GetProjectConfig (combineConfig.Id, refp, out buildEnabled) as DotNetProjectConfiguration; if ( dnpc == null ) throw new Exception ( GettextCatalog.GetString ("Could not add reference to project '{0}'", refp.Name) ); projectReferences.WriteLine (" \\"); projectReferences.Write ("\t"); pref = project.GetRelativeChildPath (dnpc.CompiledOutputName); projectReferences.Write (MakefileData.ToMakefilePath (pref)); } configSection.BuildVariablesBuilder.AppendFormat ( "PROJECT_REFERENCES = {0}\n", projectReferences.ToString() ); string buildDir = project.GetRelativeChildPath (config.OutputDirectory); configSection.BuildVariablesBuilder.AppendFormat ("BUILD_DIR = {0}\n", MakefileData.ToMakefilePath (buildDir)); // Register files built by this configuration. // Built files won't be distributed. foreach (string bfile in builtFiles) ctx.AddBuiltFile (Path.Combine (config.OutputDirectory, bfile)); DeployFileCollection deployFiles = DeployService.GetDeployFiles ( ctx.DeployContext, new SolutionItem[] { project }, config.Selector); ProcessDeployFilesForConfig (deployFiles, project, configSection, ctx, config); configSections.Add (configSection); if (!generateAutotools) { EmitCustomCommandTargets (config.CustomCommands, project, customCommands, combineConfig.Id, new CustomCommandType [] { CustomCommandType.BeforeBuild, CustomCommandType.AfterBuild, CustomCommandType.BeforeClean, CustomCommandType.AfterClean}, monitor); } else { if (config.CustomCommands.Count > 0) monitor.ReportWarning (GettextCatalog.GetString ("Custom commands are not supported for autotools based makefiles. Ignoring.")); } // Register files generated by the compiler ctx.AddBuiltFile (project.GetOutputFileName (combineConfig.Selector)); if (config.DebugMode) ctx.AddBuiltFile (project.GetOutputFileName (combineConfig.Selector) + ".mdb"); if (config.SignAssembly) { string spath = project.GetRelativeChildPath (config.AssemblyKeyFile); spath = FileService.NormalizeRelativePath (spath); extraFiles.Add (MakefileData.ToMakefilePath (spath)); } if (buildEnabled && pkgs.Count > 0) ctx.AddRequiredPackages (combineConfig.Id, pkgs); } foreach (string ef in extraFiles) extras.AppendFormat ("\\\n\t{0} ", ef); Dictionary<string, DeployFileData> commonDeployVars = new Dictionary<string, DeployFileData> (allDeployVars); foreach (ConfigSection configSection in configSections) { List<string> toRemove = new List<string> (); foreach (KeyValuePair<string, DeployFileData> pair in commonDeployVars) { if (!configSection.DeployFileVars.ContainsKey (pair.Key)) toRemove.Add (pair.Key); } foreach (string s in toRemove) commonDeployVars.Remove (s); } //emit the config sections here.. to conf_vars foreach (ConfigSection configSection in configSections) { conf_vars.AppendFormat (generateAutotools ? "if ENABLE_{0}\n" : "ifeq ($(CONFIG),{0})\n", ctx.EscapeAndUpperConfigName (configSection.Name)); conf_vars.Append (configSection.BuildVariablesBuilder.ToString ()); conf_vars.Append ("\n"); if (ctx.Switches != null) { foreach (Switch s in ctx.Switches) { conf_vars.AppendLine (string.Format (@"if ENABLE_{0} ASSEMBLY_COMPILER_FLAGS += -define:{1} endif", s.SwitchName.Replace ('-', '_').ToUpperInvariant (), s.Define)); } } foreach (KeyValuePair<string, DeployFileData> pair in allDeployVars) { string targetDeployVar = pair.Key; if (pair.Value.File.ContainsPathReferences) //Template files are not handled per-config continue; if (configSection.DeployFileVars.ContainsKey (targetDeployVar)) { //use the dfile from the config section DeployFile dfile = configSection.DeployFileVars [targetDeployVar]; string fname = MakefileData.ToMakefilePath ( FileService.AbsoluteToRelativePath ( Path.GetFullPath (project.BaseDirectory), Path.GetFullPath (dfile.SourcePath))); conf_vars.AppendFormat ("{0}_SOURCE={1}\n", targetDeployVar, fname); if (!commonDeployVars.ContainsKey (targetDeployVar)) { //FOO_DLL=$(BUILD_DIR)/foo.dll conf_vars.AppendFormat ("{0}=$(BUILD_DIR)/{1}\n", targetDeployVar, MakefileData.ToMakefilePath (dfile.RelativeTargetPath)); } } else { // not common and not part of @configSection conf_vars.AppendFormat ("{0}=\n", pair.Key); } } conf_vars.Append ( "\nendif\n\n" ); } conf_vars.AppendFormat ("AL={0}\n", (dotnetProject.TargetFramework.ClrVersion == ClrVersion.Net_2_0) ? "al2" : "al"); conf_vars.AppendFormat ("SATELLITE_ASSEMBLY_NAME=$(notdir $(basename $(ASSEMBLY))).resources.dll\n"); foreach (KeyValuePair<string, DeployFileData> pair in allDeployVars) { HandleDeployFile (pair.Value, pair.Key, project, ctx); if (commonDeployVars.ContainsKey (pair.Key)) { //FOO_DLL=$(BUILD_DIR)/foo.dll deployFileCopyVars.AppendFormat ("{0} = $(BUILD_DIR)/{1}\n", pair.Key, MakefileData.ToMakefilePath (pair.Value.File.RelativeTargetPath)); } } conf_vars.Append ('\n'); StringBuilder vars = new StringBuilder (); foreach (KeyValuePair<string, StringBuilder> pair in deployDirs) { //PROGRAM_FILES= .. etc conf_vars.AppendFormat ("{0} = {1} \n\n", pair.Key, pair.Value.ToString ()); //Build list of deploy dir variables vars.AppendFormat ("$({0}) ", pair.Key); } if (!generateAutotools) { installTarget.Insert (0, String.Format ("install-local:{0}\n", installDeps.ToString ())); installTarget.Append ("\tmake post-install-local-hook prefix=$(prefix)\n"); uninstallTarget.Insert (0, String.Format ("uninstall-local:{0}\n", installDeps.ToString ())); uninstallTarget.Append ("\tmake post-uninstall-local-hook prefix=$(prefix)\n"); } if (!generateAutotools && customCommands.Length > 0) customCommands.Insert (0, "# Targets for Custom commands\n"); templateEngine.Variables["CONFIG_VARS"] = conf_vars.ToString (); templateEngine.Variables["DEPLOY_FILE_VARS"] = vars.ToString (); templateEngine.Variables["COPY_DEPLOY_FILES_VARS"] = deployFileCopyVars.ToString(); templateEngine.Variables["COPY_DEPLOY_FILES_TARGETS"] = deployFileCopyTargets.ToString(); templateEngine.Variables["ALL_TARGET"] = (ctx.TargetSolution.BaseDirectory == project.BaseDirectory) ? "all-local" : "all"; templateEngine.Variables["INCLUDES"] = includes; templateEngine.Variables["FILES"] = files.ToString(); templateEngine.Variables["RESOURCES"] = res_files.ToString(); templateEngine.Variables["EXTRAS"] = extras.ToString(); templateEngine.Variables["DATA_FILES"] = datafiles.ToString(); templateEngine.Variables["CLEANFILES"] = vars.ToString (); if (!generateAutotools) { templateEngine.Variables["TEMPLATE_FILES_TARGETS"] = templateFilesTargets.ToString(); templateEngine.Variables["INSTALL_TARGET"] = installTarget.ToString(); templateEngine.Variables["UNINSTALL_TARGET"] = uninstallTarget.ToString(); templateEngine.Variables["CUSTOM_COMMAND_TARGETS"] = customCommands.ToString(); } // Create project specific makefile Stream stream = ctx.GetTemplateStream ( generateAutotools ? "Makefile.am.project.template" : "Makefile.noauto.project.template"); StreamReader reader = new StreamReader (stream); string txt = templateEngine.Process ( reader ); reader.Close(); makefile.Append ( txt ); monitor.Step (1); } finally { monitor.EndTask (); } return makefile; }
public Makefile Deploy (AutotoolsContext ctx, SolutionItem entry, IProgressMonitor monitor) { Makefile mkfile = new Makefile (); TranslationProject project = (TranslationProject) entry; StringBuilder files = new StringBuilder (); foreach (Translation t in project.Translations) { files.Append ("\\\n\t" + t.FileName); } string dir; if (project.OutputType == TranslationOutputType.SystemPath) { dir = ctx.DeployContext.GetResolvedPath (TargetDirectory.CommonApplicationDataRoot, "locale"); } else { dir = ctx.DeployContext.GetResolvedPath (TargetDirectory.ProgramFiles, project.RelPath); } dir = dir.Replace ("@prefix@", "$(prefix)"); dir = dir.Replace ("@PACKAGE@", "$(PACKAGE)"); TemplateEngine templateEngine = new TemplateEngine (); templateEngine.Variables ["TOP_SRCDIR"] = FileService.AbsoluteToRelativePath (project.BaseDirectory, ctx.TargetSolution.BaseDirectory); templateEngine.Variables ["FILES"] = files.ToString (); templateEngine.Variables ["BUILD_DIR"] = "."; templateEngine.Variables ["INSTALL_DIR"] = "$(DESTDIR)" + dir; templateEngine.Variables ["ALL_TARGET"] = (ctx.TargetSolution.BaseDirectory == project.BaseDirectory) ? "all-local" : "all"; StringWriter sw = new StringWriter (); string mt; if (ctx.MakefileType == MakefileType.AutotoolsMakefile) mt = "Makefile.am.template"; else mt = "Makefile.template"; using (Stream stream = GetType().Assembly.GetManifestResourceStream (mt)) { StreamReader reader = new StreamReader (stream); templateEngine.Process (reader, sw); reader.Close (); } mkfile.Append (sw.ToString ()); return mkfile; }