void Vcproj(EAPackage eapkg, string cfg) { // if nantProject is not null, it means that it needs to run generate-sln-all target instead // of the rwconfig-2.0 workflow. if(eapkg.slnTarget != null) return; // if the package is not autobuildable, then just return if(eapkg.autoBuildClean == false) return; if(eapkg.crossOnly == "true" && eapkg.nativeOnly == "true") throw new BuildException(eapkg.pkgName + ": rwconfig.native-only and rwconfig.cross-only can not both be set to true"); string configs = cfg; if(cfg.IndexOf("cross") == -1) // if the current config is native { string crossconfig = eapkg.GetExploredCrossConfig(cfg); if(crossconfig == "")// if no explored cross config, then treat it as usual { if(eapkg.crossOnly == "true") return; if(! ListContainsString(eapkg.nativeConfigs, cfg)) return; } else { if(eapkg.crossOnly == "true" || ! ListContainsString(eapkg.nativeConfigs, cfg)) configs = crossconfig; else configs = cfg + " " + crossconfig; } } if(eapkg.nativeOnly == "true" && cfg.IndexOf("cross") != -1) return; if(cfg.IndexOf("cross") != -1 && ! ListContainsString(eapkg.crossConfigs, cfg)) return; string [] groups = _groups; if(Group != "allall") { if(PackageList != "" && (! ListContainsString(PackageList, eapkg.pkgName))) { groups = new string [] {"runtime"}; } else if(eapkg.pkgName != Project.Properties["package.name"] && PackageList == "") { groups = new string [] {"runtime"}; } } Hashtable groupModules = new Hashtable(); foreach(string group in groups ) { groupModules.Add(group, new Hashtable()); if(! eapkg.groupModules.Contains(group)) { eapkg.groupModules.Add(group, new Hashtable()); } } foreach(string group in groups ) { Hashtable tempCurrModules = (Hashtable) groupModules[group]; foreach(string config in NantToVSTools.TrimAndSplit(configs)) { if(config == string.Empty) continue; // generate vsprojs for all modules of each group for current config Project proj = (Project) _projects[eapkg.pkgName + "_" + config]; if(proj == null) continue; foreach (string property in _properties.Keys) { string prop = property; if (prop.EndsWith("." + cfg + ".vsproj")) { prop = prop.Replace("." + cfg + ".vsproj", ""); proj.Properties[prop] = (string)_properties[property]; } } string constrainedBuildModules = ""; if(eapkg.pkgName != Project.Properties["package.name"]) constrainedBuildModules = (string) _properties[eapkg.pkgName + "." + group + ".buildmodules." + config]; string buildModules = eapkg.pkgName; if(group != "runtime") buildModules = group + "-" + buildModules; string supressedBuildModules = ""; if(proj.Properties.Contains(group + ".buildmodules")) { if(constrainedBuildModules == "" || constrainedBuildModules == null) buildModules = proj.Properties[group + ".buildmodules"]; else buildModules = SortConstrainedBuildModules(constrainedBuildModules, proj.Properties[group + ".buildmodules"], ref supressedBuildModules); } else if(! proj.Properties.Contains(group + ".buildtype") && ! proj.Properties.Contains(group + ".builddependencies")) { // zero module continue; } string tempModulesString = ""; ArrayList cSharpModules = new ArrayList(); ArrayList managedCPPModules = new ArrayList(); foreach(string module in NantToVSTools.TrimAndSplit(buildModules)) { if(module != string.Empty) { string moduleKey = module; if (group != "runtime" && moduleKey == group + "-" + eapkg.pkgName) { moduleKey = eapkg.pkgName; } ManagedModule mm = _managedmodulelist.Find(eapkg.pkgName + "*" + config + "*" + moduleKey + "*" + group); string tempModule = module; if(module == String.Empty) continue; // if it is a cross config, then we need to add cross- prefix to the module name if(config.ToLower().IndexOf("cross") != -1) { if(! module.StartsWith("cross-")) { proj.Properties.Add(module + ".vcproj-name-cross", "cross-" + module); _properties[eapkg.pkgName + "." + module + ".vcproj-name-cross." + config] = "cross-" + module; tempModule = "cross-" + module; } } string buildtype = (string) proj.Properties[group + "." + module + ".buildtype"]; if(buildtype == null) buildtype = (string) proj.Properties[group + ".buildtype"]; if(buildtype != null) { if (mm == null || (!mm.IsCSharp)) // not a CSharp module { if (mm != null && (!mm.IsCSharp)) managedCPPModules.Add(mm); Hashtable currModules = (Hashtable)eapkg.groupModules[group]; // check duplicate module names in other groups foreach (string othergroup in groups) { if (othergroup != group) { if (((Hashtable)eapkg.groupModules[othergroup]).Contains(tempModule)) { string errorString = String.Format("Error: Found duplicated module name {0} between groups {1} and {2} in package {3}", tempModule, group, othergroup, eapkg.pkgName); throw new BuildException(errorString); } } } // save each config for the module for the final merge step if (currModules.Contains(tempModule)) { // if two configs are the same, it means this module+config already been generated before. this only applies to cross modules that have native module depend on it if (!ListContainsString(((string)currModules[tempModule]), config)) { currModules[tempModule] = ((string)currModules[tempModule]) + " " + config; tempCurrModules[tempModule] = config; tempModulesString = tempModulesString + module + " "; } } else { currModules[tempModule] = config; tempCurrModules[tempModule] = config; // this is for merging only this config tempModulesString = tempModulesString + module + " "; } eapkg.groupModules[group] = currModules; groupModules[group] = tempCurrModules; } else // found CSharp module { cSharpModules.Add(mm); } } } } proj.Properties[PROPERTY_SKIP_BUILD_NANTTOVSTOOLS] = "true"; if (proj.Properties.Contains(group + ".buildmodules")) { proj.Properties[group + ".buildmodules.temp"] = proj.Properties[group + ".buildmodules"]; } // Always check if there are any CSharp modules if (cSharpModules.Count != 0) { //Copy project into backup location for slnmerger. foreach (ManagedModule mmodule in cSharpModules) // remove projectreference optionsets { if (IsBuildingEasharpCSC(proj)) continue; if (File.Exists(mmodule.VSProjLocation) && !File.Exists(mmodule.VSProjLocation + ".backup")) { File.Copy(mmodule.VSProjLocation, mmodule.VSProjLocation+".backup", true); // save it for merge step } } string cSharpModulesString = ""; foreach (ManagedModule mmodule in cSharpModules) // add projectreference optionsets { cSharpModulesString = CombineStrings(cSharpModulesString, mmodule.Module); if (mmodule.ProjRefCount != 0) { mmodule.SetProjRefOptionSet(proj); } } if (proj.Properties.Contains(group + ".buildmodules")) { proj.Properties[group + ".buildmodules"] = cSharpModulesString; } proj.Properties[group + ".supressedBuildModules"] = supressedBuildModules; if (group == "runtime") ProjectTargetFind(proj, TARGET_CSPROJ).Copy().Execute(); else ProjectTargetFind(proj, TARGET_CSPROJ + group).Copy().Execute(); if (proj.Properties.Contains(group + ".buildmodules")) { // restore group.buildmodules properties proj.Properties[group + ".buildmodules"] = proj.Properties[group + ".buildmodules.temp"]; } foreach (ManagedModule mmodule in cSharpModules) // remove projectreference optionsets { if (IsBuildingEasharpCSC(proj)) continue; string configVsprojFileLocation = Path.GetDirectoryName(mmodule.VSProjLocation) + Path.DirectorySeparatorChar + config + Path.DirectorySeparatorChar + Path.GetFileName(mmodule.VSProjLocation); Directory.CreateDirectory(Path.GetDirectoryName(mmodule.VSProjLocation) + Path.DirectorySeparatorChar + config); File.Copy(mmodule.VSProjLocation, configVsprojFileLocation, true); // save it for merge step if (File.Exists(mmodule.VSProjLocation + ".user")) File.Copy(mmodule.VSProjLocation + ".user", configVsprojFileLocation + ".user", true); if (mmodule.ProjRefCount != 0) mmodule.RemoveProjRefOptionSet(proj); } cSharpModules.Clear(); } if(tempCurrModules.Count != 0) // make sure to only generate the same module+config once { foreach (ManagedModule mmodule in managedCPPModules) // add projectreference optionsets { if (mmodule.ProjRefCount != 0) { mmodule.SetProjRefOptionSet(proj); } } if(proj.Properties.Contains(group + ".buildmodules")) { proj.Properties[group + ".buildmodules"] = tempModulesString; } proj.Properties["eaconfig.build.target"] = "eaconfig-vcproj"; proj.Properties["eaconfig.build.group"] = group; proj.Targets.Find("eaconfig-build-caller").Copy().Execute(); if(proj.Properties.Contains(group + ".buildmodules")) { // restore group.buildmodules properties proj.Properties[group + ".buildmodules"] = proj.Properties[group + ".buildmodules.temp"]; } foreach (ManagedModule mmodule in managedCPPModules) // remove projectreference optionsets { if (mmodule.ProjRefCount != 0) { mmodule.RemoveProjRefOptionSet(proj); } } managedCPPModules.Clear(); } if (proj.Properties.Contains(group + ".buildmodules")) { proj.Properties.Remove(group + ".buildmodules.temp"); } proj = null; } } if (IsBuildingEasharpCSC(Project)) { return; } // if only generating for one config, we don't do the merge step but should store the vcprojs' locations // for slnmaker to use later on. if(Project.Properties.Contains("generate-single-config")) { foreach(string grp in groupModules.Keys) { foreach(string mod in ((Hashtable) groupModules[grp]).Keys) { string groupDir = ""; if(grp != "runtime") groupDir = Path.DirectorySeparatorChar + grp; string currentconfig = (string) ((Hashtable) groupModules[grp])[mod]; string property = eapkg.pkgName + "." + mod + ".vcprojlocation." + currentconfig; string propertyValue = Project.Properties["package." + eapkg.pkgName + ".builddir"] + Path.DirectorySeparatorChar + currentconfig + Path.DirectorySeparatorChar + "build" + groupDir + Path.DirectorySeparatorChar + mod + ".vcproj"; _properties[property] = propertyValue; // if we are in native config but need cross module, we need to store that cross module's vsprojlocation in native config as well so that // slnmaker can find it when generating sln for native configs. if(currentconfig != cfg) _properties[eapkg.pkgName + "." + mod + ".vcprojlocation." + cfg] = propertyValue; } } } else { // We need to copy the vcproj file to the package.builddir where slnmaker looks for vcproj files. foreach(string grp in groupModules.Keys) { foreach(string mod in ((Hashtable) groupModules[grp]).Keys) { string groupDir = ""; if(grp != "runtime") groupDir = Path.DirectorySeparatorChar + grp; string config = (string) ((Hashtable) groupModules[grp])[mod]; string vcprojfilelocation = Project.Properties["package." + eapkg.pkgName + ".builddir." + config] + Path.DirectorySeparatorChar + config + Path.DirectorySeparatorChar + "build" + groupDir + Path.DirectorySeparatorChar + mod + ".vcproj"; string finalvcprojfilelocation = Project.Properties["package." + eapkg.pkgName + ".builddir." + config] + Path.DirectorySeparatorChar + mod + ".vcproj"; // a hack for pc-vc-tools config if (IsToolConfigBuild(Project.Properties["package.configs"])) { if (config.IndexOf("vc-tool-") == -1) { continue; } string ext = Path.GetExtension(finalvcprojfilelocation); if (ext == ".vcproj" || ext == ".csproj") { string fn = Path.GetFileNameWithoutExtension(finalvcprojfilelocation); string dir = Path.GetDirectoryName(finalvcprojfilelocation); finalvcprojfilelocation = Path.Combine(dir, fn + "-tools" + ext); } } File.Copy(vcprojfilelocation, finalvcprojfilelocation, true); } } } _packages[eapkg.pkgName] = eapkg; }
void SlnMaker(EAPackage eapkg, string cfg) { // if slnTarget is not null, it means that it needs to run generate-sln-all target instead // of the rwconfig-2.0 workflow. This is for backward compatibility with rwconfig 1.x if(eapkg.slnTarget != null) return; // if the package is not autobuildable, then just return if(eapkg.autoBuildClean == false) return; string configs = cfg; if(cfg.IndexOf("cross") == -1) // if the current config is native { string crossconfig = eapkg.GetExploredCrossConfig(cfg); if(crossconfig == "") { if(eapkg.crossOnly == "true") return; if(! ListContainsString(eapkg.nativeConfigs, cfg)) return; } else { // if found native-dependon-cross config, and package.configs doesn't contain this cross config // then it means no more constrain-on-buildmodules gathering operation, we can make sln for this cross config now. if(! ListContainsString(originalPackageConfigs, crossconfig)) { if(eapkg.crossOnly == "true" || ! ListContainsString(eapkg.nativeConfigs, cfg)) configs = crossconfig; else configs = cfg + " " + crossconfig; } else // if package.configs contains this cross config, then we hold this cross config because there might be more buildmodule-constrains gathering { if(eapkg.crossOnly == "true" || ! ListContainsString(eapkg.nativeConfigs, cfg)) return; } } } if(eapkg.nativeOnly == "true" && cfg.IndexOf("cross") != -1) return; if(cfg.IndexOf("cross") != -1 && ! ListContainsString(eapkg.crossConfigs, cfg)) return; string [] groups = _groups; if(Group != "allall") { if(PackageList != "" && (! ListContainsString(PackageList, eapkg.pkgName))) { groups = new string [] {"runtime"}; } else if(eapkg.pkgName != Project.Properties["package.name"] && PackageList == "") { groups = new string [] {"runtime"}; } } foreach(string config in NantToVSTools.TrimAndSplit(configs)) { if(config == string.Empty) continue; Project proj = (Project) _projects[eapkg.pkgName + "_" + config]; if(proj == null && config.IndexOf("cross") != -1) // the sln for this cross config has already been generated. continue; string packageBuilddir = proj.Properties["package.builddir"]; foreach(string grp in groups) { proj.Properties["package.nantToVSTools.slnmaker.default.output"] = packageBuilddir + "\\" + config + "\\" + eapkg.pkgName + "_" + grp + ".sln"; // Get all initialize.xml properties for all relevant packages and all other relevant properties for slnmaking. foreach(object property in _properties.Keys) { string prop = (string) property; if(prop.EndsWith("." + config)) { prop = prop.Replace("." + config, ""); proj.Properties[prop] = (string) _properties[property]; } } if(Project.Properties.Contains("generate-single-config")) { proj.Properties["generate-single-config"] = "true"; } ProjectTargetFind(proj, "sln" + grp + "-slnmaker").Copy().Execute(); AddSlnToFileSets(eapkg.pkgName, grp, packageBuilddir + "\\" + config + "\\" + eapkg.pkgName + "_" + grp + ".sln"); } _projects[eapkg.pkgName + "_" + config] = null; if(eapkg.pkgName != Project.Properties["package.name"] || (eapkg.pkgName == Project.Properties["package.name"] && config != Project.Properties["config"])) { proj.Dispose(); proj = null; } } }