Exemplo n.º 1
0
		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;
		}
Exemplo n.º 2
0
		/// <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;
		}
Exemplo n.º 3
0
        void CreateAutoGenDotSH(AutotoolsContext context, ProgressMonitor monitor)
        {
            monitor.Log.WriteLine(GettextCatalog.GetString("Creating autogen.sh"));

            TemplateEngine templateEngine = new TemplateEngine();

            templateEngine.Variables["NAME"] = solution_name;

            string fileName = Path.Combine(solution_dir, "autogen.sh");

            using (StreamWriter writer = new StreamWriter(fileName))
                using (Stream stream = context.GetTemplateStream("autogen.sh.template"))
                    using (StreamReader reader = new StreamReader(stream)) {
                        templateEngine.Process(reader, writer);
                    }

            context.AddGeneratedFile(fileName);

            // make autogen.sh executable
            if (PlatformID.Unix == Environment.OSVersion.Platform)
            {
                Syscall.chmod(fileName, FilePermissions.S_IXOTH | FilePermissions.S_IROTH | FilePermissions.S_IRWXU | FilePermissions.S_IRWXG);
            }
        }
        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);
        }
        void CreateMakefileInclude(AutotoolsContext context, IProgressMonitor monitor)
        {
            monitor.Log.WriteLine(GettextCatalog.GetString("Creating Makefile.include"));

            TemplateEngine templateEngine = new TemplateEngine();

            StringBuilder deployDirs    = new StringBuilder();
            IDictionary   dirs          = context.GetReferencedTargetDirectories();
            string        deployDirVars = String.Empty;

            foreach (DictionaryEntry e in dirs)
            {
                // It may be a sub-path
                string dir = (string)e.Key;
                int    i   = dir.IndexOf('/');
                if (i != -1)
                {
                    dir = dir.Substring(0, i);
                }
                string resolved = context.DeployContext.GetDirectory(dir);
                if (resolved == null)
                {
                    throw new InvalidOperationException("Unknown directory: " + e.Key);
                }

                // Don't use expanded dir vars in the makefile
                resolved = resolved.Replace("@expanded_", "@");

                if (i != -1)
                {
                    resolved += ((string)e.Key).Substring(i);
                }

                string var   = (string)e.Value;
                string dname = var.ToLower().Replace("_", String.Empty);
                deployDirs.AppendFormat("{0}dir = {1}\n", dname, resolved);
                deployDirs.AppendFormat("{0}_DATA = $({1})\n", dname, var);
                deployDirVars += "$(" + var + ") ";
            }

            templateEngine.Variables["DEPLOY_DIRS"]        = deployDirs.ToString();
            templateEngine.Variables["DEPLOY_FILES_CLEAN"] = deployDirVars;
            templateEngine.Variables["CONFIG_MAKE_DEP"]    = generateAutotools ? String.Empty : "$(top_srcdir)/config.make";
            if (generateAutotools)
            {
                templateEngine.Variables["WRAPPER_SED"] = String.Empty;
            }
            else
            {
                templateEngine.Variables["WRAPPER_SED"] =
                    "\n$2: $2.in $(top_srcdir)/config.make\n" +
                    "\tsed -e \"s,@prefix@,$(prefix),\"" +
                    " -e \"s,@PACKAGE@,$(PACKAGE),\"" +
                    " -e \"s,@expanded_libdir@,$(libdir),\"" +
                    " -e \"s,@expanded_bindir@,$(bindir),\"" +
                    " -e \"s,@expanded_datadir@,$(datadir),\"" +
                    " < $2.in > $2";
            }
            templateEngine.Variables["VALID_CULTURES"] = CultureNames;

            string fileName = Path.Combine(solution_dir, "Makefile.include");

            Stream stream = context.GetTemplateStream("Makefile.include");

            StreamReader reader = new StreamReader(stream);
            StreamWriter writer = new StreamWriter(fileName);

            templateEngine.Process(reader, writer);

            reader.Close();
            writer.Close();

            context.AddGeneratedFile(fileName);
        }
        void CreateConfigureScript(Solution solution, string defaultConf, AutotoolsContext ctx, IProgressMonitor monitor)
        {
            monitor.Log.WriteLine(GettextCatalog.GetString("Creating configure script"));

            TemplateEngine templateEngine = new TemplateEngine();

            // Build list of configurations
            StringBuilder sbConfig = new StringBuilder();

            sbConfig.Append("\"");
            foreach (string config in ctx.GetConfigurations())
            {
                sbConfig.AppendFormat(" {0}", config);
            }
            sbConfig.Append("\"");

            // Build list of packages required by all configs
            string commonPackages = String.Format("common_packages=\"{0}\"", GetPackageListFromSet(context.GetCommonRequiredPackages()));

            // Build list of packages required per config
            StringBuilder requiredPackages = new StringBuilder();

            foreach (SolutionConfiguration config in solution.Configurations)
            {
                Set <SystemPackage> pkgs = context.GetRequiredPackages(config.Id, true);
                if (pkgs == null || pkgs.Count == 0)
                {
                    continue;
                }

                if (requiredPackages.Length > 0)
                {
                    requiredPackages.Append("\n");
                }
                requiredPackages.AppendFormat("required_packages_{0}=\"{1}\"",
                                              context.EscapeAndUpperConfigName(config.Id),
                                              GetPackageListFromSet(pkgs));
            }

            templateEngine.Variables ["VERSION"]           = solution_version;
            templateEngine.Variables ["PACKAGE"]           = solution.Name.ToLower();
            templateEngine.Variables ["DEFAULT_CONFIG"]    = ctx.EscapeAndUpperConfigName(defaultConf);
            templateEngine.Variables ["CONFIGURATIONS"]    = sbConfig.ToString();
            templateEngine.Variables ["COMMON_PACKAGES"]   = commonPackages.ToString();
            templateEngine.Variables ["REQUIRED_PACKAGES"] = requiredPackages.ToString();


            Stream stream = context.GetTemplateStream("configure.template");

            string       filename = Path.Combine(solution_dir, "configure");
            StreamReader reader   = new StreamReader(stream);
            StreamWriter writer   = new StreamWriter(filename);

            templateEngine.Process(reader, writer);
            reader.Close();
            writer.Close();

            ctx.AddGeneratedFile(filename);

            if (PlatformID.Unix == Environment.OSVersion.Platform)
            {
                Syscall.chmod(filename, FilePermissions.S_IXOTH | FilePermissions.S_IROTH | FilePermissions.S_IRWXU | FilePermissions.S_IRWXG);
            }
        }
        void CreateConfigureDotAC(Solution solution, string defaultConf, IProgressMonitor monitor, AutotoolsContext context)
        {
            monitor.Log.WriteLine(GettextCatalog.GetString("Creating configure.ac"));
            TemplateEngine templateEngine = new TemplateEngine();

            templateEngine.Variables["WARNING"] = "Warning: This is an automatically generated file, do not edit!";

            // add solution configuration options
            StringBuilder config_options = new StringBuilder();

            foreach (SolutionConfiguration config in solution.Configurations)
            {
                string name   = context.EscapeAndUpperConfigName(config.Id).ToLower();
                string def    = config.Id == defaultConf ? "YES" : "NO";
                string ac_var = "enable_" + name;

                // test to see if a configuration was enabled
                config_options.AppendFormat("AC_ARG_ENABLE({0},\n", name);
                config_options.AppendFormat("	AC_HELP_STRING([--enable-{0}],\n", name);
                config_options.AppendFormat("		[Use '{0}' Configuration [default={1}]]),\n", context.EscapeAndUpperConfigName(config.Id), def);
                config_options.AppendFormat("		{0}=yes, {0}=no)\n", ac_var);
                config_options.AppendFormat("AM_CONDITIONAL({0}, test x${1} = xyes)\n", ac_var.ToUpper(), ac_var);

                // if yes, populate some vars
                config_options.AppendFormat("if test \"x${0}\" = \"xyes\" ; then\n", ac_var);
//				AppendConfigVariables ( combine, config.Name, config_options );
                config_options.Append("	CONFIG_REQUESTED=\"yes\"\nfi\n");
            }

            // if no configuration was specified, set to default (if there is a default)
            if (defaultConf != null)
            {
                config_options.Append("if test -z \"$CONFIG_REQUESTED\" ; then\n");
//				AppendConfigVariables ( combine, defaultConf, config_options );
                config_options.AppendFormat("	AM_CONDITIONAL(ENABLE_{0}, true)\n", context.EscapeAndUpperConfigName(defaultConf));
                config_options.AppendFormat("\tenable_{0}=yes\n", context.EscapeAndUpperConfigName(defaultConf).ToLower());
                config_options.Append("fi\n");
            }

            // Add specific user switch
            if (switchs != null)
            {
                foreach (Switch s in switchs)
                {
                    string name = s.SwitchName.ToLowerInvariant();

                    config_options.AppendLine(string.Format(@"AC_ARG_ENABLE({0},
	AC_HELP_STRING([--enable-{0}],
		[{1}]),
		enable_{2}=yes, enable_{2}=no)
AM_CONDITIONAL(ENABLE_{3}, test x$enable_{2} = xyes)",
                                                            name, s.HelpStr, name.Replace('-', '_'), name.Replace('-', '_').ToUpperInvariant()));
                }
            }

            templateEngine.Variables ["CONFIG_OPTIONS"] = config_options.ToString();

            // build compiler checks
            StringBuilder compiler_checks = new StringBuilder();

            foreach (string compiler in context.GetCommandChecks())
            {
                compiler_checks.AppendFormat("AC_PATH_PROG({0}, {1}, no)\n", compiler.ToUpper(), compiler);
                compiler_checks.AppendFormat("if test \"x${0}\" = \"xno\"; then\n", compiler.ToUpper());
                compiler_checks.AppendFormat("        AC_MSG_ERROR([{0} Not found])\n", compiler);
                compiler_checks.Append("fi\n");
            }
            templateEngine.Variables["COMPILER_CHECKS"] = compiler_checks.ToString();

            // build list of *.in files
            StringBuilder configFiles = new StringBuilder();
            string        tmpmf       = null;

            foreach (string makefile in context.GetAutoConfFiles())
            {
                tmpmf = FileService.AbsoluteToRelativePath(solution_dir, makefile);
                if (PlatformID.Unix != Environment.OSVersion.Platform)
                {
                    tmpmf = tmpmf.Replace("\\", "/");
                }

                AutotoolsContext.CheckSpaces(tmpmf);
                configFiles.Append(FileService.NormalizeRelativePath(tmpmf));
                configFiles.Append("\n");
            }
            templateEngine.Variables["CONFIG_FILES"] = configFiles.ToString();

            // build list of pkgconfig checks we must make
            StringWriter packageChecks = new StringWriter();

            packageChecks.WriteLine("dnl package checks, common for all configs");
            Set <SystemPackage> commonPackages = context.GetCommonRequiredPackages();

            foreach (SystemPackage pkg in commonPackages)
            {
                packageChecks.WriteLine("PKG_CHECK_MODULES([{0}], [{1}])", AutotoolsContext.GetPkgConfigVariable(pkg.Name), pkg.Name);
            }

            packageChecks.WriteLine("\ndnl package checks, per config");
            foreach (SolutionConfiguration config in solution.Configurations)
            {
                Set <SystemPackage> pkgs = context.GetRequiredPackages(config.Id, true);
                if (pkgs == null || pkgs.Count == 0)
                {
                    continue;
                }

                packageChecks.WriteLine(@"if test ""x$enable_{0}"" = ""xyes""; then",
                                        context.EscapeAndUpperConfigName(config.Id).ToLower());

                foreach (SystemPackage pkg in pkgs)
                {
                    packageChecks.WriteLine("\tPKG_CHECK_MODULES([{0}], [{1}])", AutotoolsContext.GetPkgConfigVariable(pkg.Name), pkg.Name);
                }
                packageChecks.WriteLine("fi");
            }
            templateEngine.Variables["PACKAGE_CHECKS"] = packageChecks.ToString();
            templateEngine.Variables["SOLUTION_NAME"]  = solution_name;
            templateEngine.Variables["VERSION"]        = solution_version;

            string configureFileName = Path.Combine(solution_dir, "configure.ac");

            StreamWriter writer = new StreamWriter(configureFileName);
            Stream       stream = context.GetTemplateStream("configure.ac.template");
            StreamReader reader = new StreamReader(stream);

            templateEngine.Process(reader, writer);

            reader.Close();
            writer.Close();
            context.AddGeneratedFile(configureFileName);
        }
		void CreateMakefileInclude (AutotoolsContext context, IProgressMonitor monitor)
		{
			monitor.Log.WriteLine ( GettextCatalog.GetString ("Creating Makefile.include") );
			
			TemplateEngine templateEngine = new TemplateEngine();
			
			StringBuilder deployDirs = new StringBuilder ();
			IDictionary dirs = context.GetReferencedTargetDirectories ();
			string deployDirVars = String.Empty;
			
			foreach (DictionaryEntry e in dirs) {
				// It may be a sub-path
				string dir = (string) e.Key;
				int i = dir.IndexOf ('/');
				if (i != -1)
					dir = dir.Substring (0, i);
				string resolved = context.DeployContext.GetDirectory (dir);
				if (resolved == null)
					throw new InvalidOperationException ("Unknown directory: " + e.Key);

				// Don't use expanded dir vars in the makefile
				resolved = resolved.Replace ("@expanded_", "@");
				
				if (i != -1)
					resolved += ((string)e.Key).Substring (i);
				
				string var = (string) e.Value;
				string dname = var.ToLower ().Replace ("_", String.Empty);
				deployDirs.AppendFormat ("{0}dir = {1}\n", dname, resolved);
				deployDirs.AppendFormat ("{0}_DATA = $({1})\n", dname, var);
				deployDirVars += "$(" + var + ") ";
			}
			
			templateEngine.Variables["DEPLOY_DIRS"] = deployDirs.ToString();
			templateEngine.Variables["DEPLOY_FILES_CLEAN"] = deployDirVars;
			templateEngine.Variables["CONFIG_MAKE_DEP"] = generateAutotools ? String.Empty : "$(top_srcdir)/config.make";
			if (generateAutotools)
				templateEngine.Variables["WRAPPER_SED"] = String.Empty;
			else
				templateEngine.Variables["WRAPPER_SED"] =
					"\n$2: $2.in $(top_srcdir)/config.make\n" +
					"\tsed -e \"s,@prefix@,$(prefix),\"" +
					" -e \"s,@PACKAGE@,$(PACKAGE),\"" +
					" -e \"s,@expanded_libdir@,$(libdir),\"" +
					" -e \"s,@expanded_bindir@,$(bindir),\"" +
					" -e \"s,@expanded_datadir@,$(datadir),\"" +
					" < $2.in > $2";
			templateEngine.Variables["VALID_CULTURES"] = CultureNames;

			string fileName = Path.Combine (solution_dir, "Makefile.include");

			Stream stream = context.GetTemplateStream ("Makefile.include");

			StreamReader reader = new StreamReader(stream);
			StreamWriter writer = new StreamWriter(fileName);

			templateEngine.Process(reader, writer);

			reader.Close();
			writer.Close();

			context.AddGeneratedFile (fileName);
		}
		void CreateConfigureScript (Solution solution, string defaultConf, AutotoolsContext ctx, IProgressMonitor monitor)
		{
			monitor.Log.WriteLine ( GettextCatalog.GetString ("Creating configure script") );

			TemplateEngine templateEngine = new TemplateEngine ();

			// Build list of configurations
			StringBuilder sbConfig = new StringBuilder ();
			sbConfig.Append ("\"");
			foreach (string config in ctx.GetConfigurations ())
				sbConfig.AppendFormat (" {0}", config);
			sbConfig.Append ("\"");

			// Build list of packages required by all configs
			string commonPackages = String.Format ("common_packages=\"{0}\"", GetPackageListFromSet (context.GetCommonRequiredPackages ()));

			// Build list of packages required per config
			StringBuilder requiredPackages = new StringBuilder ();
			foreach (SolutionConfiguration config in solution.Configurations) {
				Set<SystemPackage> pkgs = context.GetRequiredPackages (config.Id, true);
				if (pkgs == null || pkgs.Count == 0)
					continue;

				if (requiredPackages.Length > 0)
					requiredPackages.Append ("\n");
				requiredPackages.AppendFormat ("required_packages_{0}=\"{1}\"",
						context.EscapeAndUpperConfigName (config.Id),
						GetPackageListFromSet (pkgs));
			}

			templateEngine.Variables ["VERSION"] = solution_version;
			templateEngine.Variables ["PACKAGE"] = solution.Name.ToLower ();
			templateEngine.Variables ["DEFAULT_CONFIG"] = ctx.EscapeAndUpperConfigName (defaultConf);
			templateEngine.Variables ["CONFIGURATIONS"] = sbConfig.ToString ();
			templateEngine.Variables ["COMMON_PACKAGES"] = commonPackages.ToString ();
			templateEngine.Variables ["REQUIRED_PACKAGES"] = requiredPackages.ToString ();


			Stream stream = context.GetTemplateStream ("configure.template");

			string filename = Path.Combine (solution_dir, "configure");
			StreamReader reader = new StreamReader (stream);
			StreamWriter writer = new StreamWriter (filename);
			templateEngine.Process(reader, writer);
			reader.Close ();
			writer.Close ();

			ctx.AddGeneratedFile (filename);

			if (PlatformID.Unix == Environment.OSVersion.Platform)
				Syscall.chmod ( filename , FilePermissions.S_IXOTH | FilePermissions.S_IROTH | FilePermissions.S_IRWXU | FilePermissions.S_IRWXG );
		}
		void CreateConfigureDotAC (Solution solution, string defaultConf, IProgressMonitor monitor, AutotoolsContext context)
		{
			monitor.Log.WriteLine ( GettextCatalog.GetString ("Creating configure.ac") );
			TemplateEngine templateEngine = new TemplateEngine();			
			templateEngine.Variables["WARNING"] = "Warning: This is an automatically generated file, do not edit!";		
			
			// add solution configuration options
			StringBuilder config_options = new StringBuilder ();
			foreach ( SolutionConfiguration config in solution.Configurations )
			{
				string name = context.EscapeAndUpperConfigName (config.Id).ToLower();
				string def = config.Id == defaultConf ? "YES" : "NO";
				string ac_var = "enable_" + name;

				// test to see if a configuration was enabled
				config_options.AppendFormat ( "AC_ARG_ENABLE({0},\n", name );
				config_options.AppendFormat ("	AC_HELP_STRING([--enable-{0}],\n", name );
				config_options.AppendFormat ("		[Use '{0}' Configuration [default={1}]]),\n", context.EscapeAndUpperConfigName (config.Id), def );
				config_options.AppendFormat ( "		{0}=yes, {0}=no)\n", ac_var );
				config_options.AppendFormat ( "AM_CONDITIONAL({0}, test x${1} = xyes)\n", ac_var.ToUpper(), ac_var );

				// if yes, populate some vars
				config_options.AppendFormat ( "if test \"x${0}\" = \"xyes\" ; then\n", ac_var );
//				AppendConfigVariables ( combine, config.Name, config_options );
				config_options.Append ( "	CONFIG_REQUESTED=\"yes\"\nfi\n" );
			}

			// if no configuration was specified, set to default (if there is a default)
			if (defaultConf != null)
			{
				config_options.Append ( "if test -z \"$CONFIG_REQUESTED\" ; then\n" );
//				AppendConfigVariables ( combine, defaultConf, config_options );
				config_options.AppendFormat ( "	AM_CONDITIONAL(ENABLE_{0}, true)\n", context.EscapeAndUpperConfigName (defaultConf));
				config_options.AppendFormat ("\tenable_{0}=yes\n", context.EscapeAndUpperConfigName (defaultConf).ToLower ());
				config_options.Append ("fi\n");
			}

			// Add specific user switch
			if (switchs != null) {
				foreach (Switch s in switchs) {
					string name = s.SwitchName.ToLowerInvariant ();
					
					config_options.AppendLine (string.Format (@"AC_ARG_ENABLE({0},
	AC_HELP_STRING([--enable-{0}],
		[{1}]),
		enable_{2}=yes, enable_{2}=no)
AM_CONDITIONAL(ENABLE_{3}, test x$enable_{2} = xyes)", 
				                       name, s.HelpStr, name.Replace ('-', '_'), name.Replace ('-', '_').ToUpperInvariant ()));
				}
			}
			
			templateEngine.Variables ["CONFIG_OPTIONS"] = config_options.ToString();

			// build compiler checks
			StringBuilder compiler_checks = new StringBuilder();
			foreach (string compiler in context.GetCommandChecks () ) 
			{
				compiler_checks.AppendFormat ("AC_PATH_PROG({0}, {1}, no)\n", compiler.ToUpper(), compiler);
				compiler_checks.AppendFormat ("if test \"x${0}\" = \"xno\"; then\n", compiler.ToUpper() );
				compiler_checks.AppendFormat ("        AC_MSG_ERROR([{0} Not found])\n", compiler );
				compiler_checks.Append("fi\n");
			}
			templateEngine.Variables["COMPILER_CHECKS"] = compiler_checks.ToString();

			// build list of *.in files
			StringBuilder configFiles = new StringBuilder();
			string tmpmf = null;
			foreach (string makefile in context.GetAutoConfFiles () ) 
			{
				tmpmf = FileService.AbsoluteToRelativePath ( solution_dir, makefile );
				if (PlatformID.Unix != Environment.OSVersion.Platform)
					tmpmf = tmpmf.Replace("\\","/");

				AutotoolsContext.CheckSpaces (tmpmf);
				configFiles.Append(FileService.NormalizeRelativePath (tmpmf));
				configFiles.Append("\n");
			}
			templateEngine.Variables["CONFIG_FILES"] = configFiles.ToString();

			// build list of pkgconfig checks we must make
			StringWriter packageChecks = new StringWriter();
			packageChecks.WriteLine ("dnl package checks, common for all configs");
			Set<SystemPackage> commonPackages = context.GetCommonRequiredPackages ();
			foreach (SystemPackage pkg in commonPackages)
				packageChecks.WriteLine("PKG_CHECK_MODULES([{0}], [{1}])", AutotoolsContext.GetPkgConfigVariable (pkg.Name), pkg.Name);

			packageChecks.WriteLine ("\ndnl package checks, per config");
			foreach (SolutionConfiguration config in solution.Configurations) {
				Set<SystemPackage> pkgs = context.GetRequiredPackages (config.Id, true);
				if (pkgs == null || pkgs.Count == 0)
					continue;

				packageChecks.WriteLine (@"if test ""x$enable_{0}"" = ""xyes""; then",
				                         context.EscapeAndUpperConfigName (config.Id).ToLower());

				foreach (SystemPackage pkg in pkgs)
					packageChecks.WriteLine("\tPKG_CHECK_MODULES([{0}], [{1}])", AutotoolsContext.GetPkgConfigVariable (pkg.Name), pkg.Name);
				packageChecks.WriteLine ("fi");
			}
			templateEngine.Variables["PACKAGE_CHECKS"] = packageChecks.ToString();
			templateEngine.Variables["SOLUTION_NAME"] = solution_name;
			templateEngine.Variables["VERSION"] = solution_version;

			string configureFileName = Path.Combine (solution_dir, "configure.ac");

			StreamWriter writer = new StreamWriter(configureFileName);
			Stream stream = context.GetTemplateStream ("configure.ac.template");
			StreamReader reader = new StreamReader(stream);

			templateEngine.Process(reader, writer);

			reader.Close();
			writer.Close();
			context.AddGeneratedFile (configureFileName);
		}
		void CreateAutoGenDotSH (AutotoolsContext context, IProgressMonitor monitor)
		{
			monitor.Log.WriteLine ( GettextCatalog.GetString ("Creating autogen.sh") );

			TemplateEngine templateEngine = new TemplateEngine();			

			templateEngine.Variables["NAME"] = solution_name;

			string fileName = Path.Combine (solution_dir, "autogen.sh");

			StreamWriter writer = new StreamWriter( fileName );

			Stream stream = context.GetTemplateStream ("autogen.sh.template");
			StreamReader reader = new StreamReader(stream);

			templateEngine.Process(reader, writer);

			reader.Close();
			writer.Close();

			context.AddGeneratedFile (fileName);

			// make autogen.sh executable
			if (PlatformID.Unix == Environment.OSVersion.Platform)
				Syscall.chmod ( fileName , FilePermissions.S_IXOTH | FilePermissions.S_IROTH | FilePermissions.S_IRWXU | FilePermissions.S_IRWXG );
		}
		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;
		}