// Populates configSection.DeployFileVars with unique DeployFiles for a particular config void ProcessDeployFilesForConfig(DeployFileCollection deployFiles, Project project, ConfigSection configSection, AutotoolsContext ctx, DotNetProjectConfiguration config) { //@deployFiles can have duplicates Dictionary <string, DeployFile> uniqueDeployFiles = new Dictionary <string, DeployFile> (); foreach (DeployFile dfile in deployFiles) { if (dfile.SourcePath == project.GetOutputFileName(configSection.Selector)) { continue; } // DeployFileCollection can have duplicates, ignore them string key = dfile.RelativeTargetPath; if (!dfile.ContainsPathReferences) { key += dfile.SourcePath; } if (uniqueDeployFiles.ContainsKey(key)) { continue; } uniqueDeployFiles [key] = dfile; string targetDeployVar = GetDeployVar(deployFileVars, dfile.RelativeTargetPath); configSection.DeployFileVars [targetDeployVar] = dfile; DeployFileData data = new DeployFileData(); data.File = dfile; data.Configuration = config; allDeployVars [targetDeployVar] = data; } }
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) { 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_2_0: resgen = "resgen2"; break; case ClrVersion.Net_1_1: resgen = "resgen1"; 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); }
// Populates configSection.DeployFileVars with unique DeployFiles for a particular config void ProcessDeployFilesForConfig (DeployFileCollection deployFiles, Project project, ConfigSection configSection, AutotoolsContext ctx, DotNetProjectConfiguration config) { //@deployFiles can have duplicates Dictionary<string, DeployFile> uniqueDeployFiles = new Dictionary<string, DeployFile> (); foreach (DeployFile dfile in deployFiles) { if (dfile.SourcePath == project.GetOutputFileName (configSection.Selector)) continue; // DeployFileCollection can have duplicates, ignore them string key = dfile.RelativeTargetPath; if (!dfile.ContainsPathReferences) key += dfile.SourcePath; if (uniqueDeployFiles.ContainsKey (key)) continue; uniqueDeployFiles [key] = dfile; string targetDeployVar = GetDeployVar (deployFileVars, dfile.RelativeTargetPath); configSection.DeployFileVars [targetDeployVar] = dfile; DeployFileData data = new DeployFileData (); data.File = dfile; data.Configuration = config; allDeployVars [targetDeployVar] = data; } }