retag
[mcs.git] / tools / prj2make / MdPrjHelper.cs
blob2f86c2b6274b0c42772e591df603aac3c7158f89
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Text;
5 using System.Text.RegularExpressions;
6 using System.Xml;
7 using System.Xml.Serialization;
8 using System.Diagnostics;
10 namespace Mfconsulting.General.Prj2Make
12 public class CmbxMaker
14 public static string slash;
15 static Hashtable projNameInfo = new Hashtable();
16 static Hashtable projGuidInfo = new Hashtable();
17 private Mfconsulting.General.Prj2Make.Schema.Cmbx.Combine m_cmbObject;
18 private bool m_bIsUnix;
19 private bool m_bIsMcs;
20 private bool m_bIsUsingLib;
22 // Flag use to determine if the LIB variable will be used in
23 // the Makefile that prj2make generates
24 public bool IsUsingLib
26 get{ return m_bIsUsingLib; }
27 set{ m_bIsUsingLib = value; }
30 // Determines if the makefile is intended for nmake or gmake for urposes of path separator character
31 public bool IsUnix
33 get{ return m_bIsUnix; }
34 set{ m_bIsUnix = value; }
37 // Determines if using MCS or CSC
38 public bool IsMcs
40 get{ return m_bIsMcs; }
41 set{ m_bIsMcs = value; }
44 public Mfconsulting.General.Prj2Make.Schema.Cmbx.Combine Solucion {
45 get { return m_cmbObject; }
48 public CmbxMaker()
50 m_bIsUnix = false;
51 m_bIsMcs = false;
52 m_bIsUsingLib = false;
55 // Combine desirialization
56 protected Mfconsulting.General.Prj2Make.Schema.Cmbx.Combine LoadCmbFromFile (string strIn)
58 FileStream fs = new FileStream (strIn, FileMode.Open);
60 XmlSerializer xmlSer = new XmlSerializer (typeof(Mfconsulting.General.Prj2Make.Schema.Cmbx.Combine));
61 Mfconsulting.General.Prj2Make.Schema.Cmbx.Combine cmbObj = (Mfconsulting.General.Prj2Make.Schema.Cmbx.Combine) xmlSer.Deserialize (fs);
63 fs.Close();
65 return (cmbObj);
68 protected void ParseMdCsProj(string fname)
70 string projectName;
72 PrjxInfo pi = new PrjxInfo(m_bIsUnix, m_bIsMcs, fname);
73 projectName = pi.name;
74 projNameInfo[projectName] = pi;
77 protected void ParseCombine(string fname)
79 string CombineFilePath = fname;
81 // convert backslashes to slashes
82 CombineFilePath = CombineFilePath.Replace("\\", "/");
84 // loads the file in order to deserialize and
85 // build the object graph
86 try {
87 m_cmbObject = LoadCmbFromFile (CombineFilePath);
88 } catch (Exception exc) {
90 Console.WriteLine (
91 String.Format ("Could not load the file {0}\nException: {1}",
92 CombineFilePath,
93 exc.Message)
95 return;
98 foreach(Mfconsulting.General.Prj2Make.Schema.Cmbx.Entry ent in m_cmbObject.Entries)
100 string projectName = System.IO.Path.GetFileNameWithoutExtension(ent.filename);
101 string csprojPath = ent.filename;
103 if (csprojPath.EndsWith(".prjx"))
105 PrjxInfo pi = new PrjxInfo(m_bIsUnix, m_bIsMcs, csprojPath);
107 projNameInfo[projectName] = pi;
112 public string MdCmbxHelper(bool isUnixMode, bool isMcsMode, bool isSln, string slnFile)
114 bool noCommonTargets = false;
115 bool noProjectTargets = false;
116 bool noFlags = false;
117 int nPos = -1;
118 StringBuilder MakefileBuilder = new StringBuilder();
120 m_bIsUnix = isUnixMode;
121 m_bIsMcs = isMcsMode;
123 if(m_bIsUnix == true && m_bIsMcs == true)
125 m_bIsUsingLib = true;
128 if (m_bIsUnix)
130 slash = "/";
132 else
134 slash = "\\";
139 string d = Path.GetDirectoryName(slnFile);
141 if (d != "")
142 Directory.SetCurrentDirectory(d);
144 if (isSln == true) {
145 // We invoke the ParseSolution
146 // by passing the file obtained
147 ParseCombine (slnFile);
148 } else {
150 // We invoke the ParseMsCsProj
151 // by passing the file obtained
152 ParseMdCsProj (slnFile);
155 if (!noFlags)
157 if (m_bIsUnix) // gmake
159 MakefileBuilder.Append("ifndef TARGET\n");
160 MakefileBuilder.Append("\tTARGET=./bin/Debug\n");
161 MakefileBuilder.Append("else\n");
162 MakefileBuilder.Append("\tTARGET=./bin/$(TARGET)\n");
163 MakefileBuilder.Append("endif\n\n");
165 if (m_bIsMcs == false)
167 MakefileBuilder.Append("MCS=csc\n");
168 MakefileBuilder.Append("MCSFLAGS=-nologo\n\n");
169 MakefileBuilder.Append("ifdef (RELEASE)\n");
170 MakefileBuilder.Append("\tMCSFLAGS=$(MCSFLAGS) -optimize+ -d:TRACE\n");
171 MakefileBuilder.Append("else\n");
172 MakefileBuilder.Append("\tMCSFLAGS=$(MCSFLAGS) -debug+ -d:TRACE,DEBUG\n");
173 MakefileBuilder.Append("endif\n");
175 else
177 MakefileBuilder.Append("MCS=mcs\n");
178 MakefileBuilder.Append("ifndef (RELEASE)\n");
179 MakefileBuilder.Append("\tMCSFLAGS=-debug \n");
180 MakefileBuilder.Append("endif\n");
181 // Define and add the information used in the -lib: arguments passed to the
182 // compiler to assist in finding non-fullyqualified assembly references.
183 if(m_bIsUsingLib == true)
185 string strlibDir = PkgConfigInvoker.GetPkgVariableValue("mono", "libdir");
187 if (strlibDir == null)
189 strlibDir = "/usr/lib";
192 MakefileBuilder.AppendFormat("\nLIBS=-lib:{0} -lib:{1}\n\n",
193 Utils.Escape (Path.Combine(strlibDir.TrimEnd(), "mono/1.0")),
194 Utils.Escape (Path.Combine(strlibDir.TrimEnd(), "mono/gtk-sharp"))
199 else // nmake
201 MakefileBuilder.Append("!if !defined (TARGET)\n");
202 MakefileBuilder.Append("TARGET=.\\bin\\Debug\n");
203 MakefileBuilder.Append("!else\n");
204 MakefileBuilder.Append("TARGET=.\\bin\\$(TARGET)\n");
205 MakefileBuilder.Append("!endif\n\n");
207 if (m_bIsMcs == false)
209 MakefileBuilder.Append("MCS=csc\n");
210 MakefileBuilder.Append("MCSFLAGS=-nologo\n\n");
211 MakefileBuilder.Append("!if !defined(RELEASE)\n");
212 MakefileBuilder.Append("MCSFLAGS=$(MCSFLAGS) -optimize+ -d:TRACE\n");
213 MakefileBuilder.Append("!else\n");
214 MakefileBuilder.Append("MCSFLAGS=$(MCSFLAGS) -debug+ -d:TRACE,DEBUG\n");
215 MakefileBuilder.Append("!endif\n");
217 else
219 MakefileBuilder.Append("MCS=mcs\n");
220 MakefileBuilder.Append("!if !defined(RELEASE)\n");
221 MakefileBuilder.Append("MCSFLAGS=-debug \n");
222 MakefileBuilder.Append("!endif\n");
226 MakefileBuilder.Append("\n");
228 else
230 MakefileBuilder.Append("!if !defined(MCS)\n");
231 MakefileBuilder.Append("!error You must provide MCS when making\n");
232 MakefileBuilder.Append("!endif\n\n");
235 foreach (PrjxInfo prjI in projNameInfo.Values)
237 MakefileBuilder.AppendFormat("{0}=$(TARGET){1}{2}\n", prjI.makename_ext, slash, prjI.assembly_name);
238 MakefileBuilder.AppendFormat("{0}_PDB=$(TARGET){1}{2}\n", prjI.makename, slash, prjI.assembly_name.Replace(".dll",".pdb"));
239 MakefileBuilder.AppendFormat("{0}_SRC={1}\n", prjI.makename, prjI.src);
240 MakefileBuilder.AppendFormat("{0}_RES={1}\n\n", prjI.makename, prjI.res);
244 foreach (PrjxInfo pi in projNameInfo.Values)
246 string refs = "";
247 string deps = "";
249 foreach (Mfconsulting.General.Prj2Make.Schema.Prjx.Reference rf in pi.Proyecto.References)
251 if (refs != "")
252 refs += " ";
254 string assemblyName = rf.refto;
256 // HACK - under Unix filenames are case sensitive
257 // Under Windows there's no agreement on Xml vs XML ;-)
258 if (0 == String.Compare(assemblyName, "System.Xml", true))
260 assemblyName = "System.Xml";
263 // Check to see if there is a coma in the
264 // reference. This could indicate a GAC
265 // style reference
266 nPos = assemblyName.IndexOf(',');
267 if(nPos == -1)
269 if (System.IO.Path.GetExtension(assemblyName).ToUpper().CompareTo(".DLL") == 0)
271 refs += "-r:" + assemblyName;
273 else
275 refs += "-r:" + assemblyName + ".dll";
278 else
280 refs += "-r:" + assemblyName.Substring(0, nPos) + ".dll";
284 MakefileBuilder.AppendFormat("$({0}): $({1}_SRC) {2}\n", pi.makename_ext, pi.makename, deps);
286 if (isUnixMode)
288 MakefileBuilder.Append("\t-mkdir -p $(TARGET)\n");
290 else
292 MakefileBuilder.Append("\t-md $(TARGET)\n");
295 MakefileBuilder.Append("\t$(MCS) $(MCSFLAGS)");
297 // Test to see if any configuratino has the Allow unsafe blocks on
298 if(pi.AllowUnsafeCode == true ) {
299 MakefileBuilder.Append(" -unsafe");
302 // Test for LIBS usage
303 if(m_bIsUsingLib == true) {
304 MakefileBuilder.Append(" $(LIBS)");
307 MakefileBuilder.AppendFormat(" {2}{3} -out:$({0}) $({1}_RES) $({1}_SRC)\n",
308 pi.makename_ext, pi.makename, refs, pi.switches);
310 MakefileBuilder.Append("\n");
313 if (!noCommonTargets)
315 MakefileBuilder.Append("\n");
316 MakefileBuilder.Append("# common targets\n\n");
317 MakefileBuilder.Append("all:\t");
319 bool first = true;
321 foreach (PrjxInfo pi in projNameInfo.Values)
323 if (!first)
325 MakefileBuilder.Append(" \\\n\t");
327 MakefileBuilder.AppendFormat("$({0})", pi.makename_ext);
328 first = false;
330 MakefileBuilder.Append("\n\n");
332 MakefileBuilder.Append("clean:\n");
334 foreach (PrjxInfo pi in projNameInfo.Values)
336 if (isUnixMode)
338 MakefileBuilder.AppendFormat("\t-rm -f \"$({0})\" 2> /dev/null\n", pi.makename_ext);
339 MakefileBuilder.AppendFormat("\t-rm -f \"$({0}_PDB)\" 2> /dev/null\n", pi.makename);
341 else
343 MakefileBuilder.AppendFormat("\t-del \"$({0})\" 2> nul\n", pi.makename_ext);
344 MakefileBuilder.AppendFormat("\t-del \"$({0}_PDB)\" 2> nul\n", pi.makename);
347 MakefileBuilder.Append("\n");
350 if (!noProjectTargets)
352 MakefileBuilder.Append("\n");
353 MakefileBuilder.Append("# project names as targets\n\n");
354 foreach (PrjxInfo pi in projNameInfo.Values)
356 MakefileBuilder.AppendFormat("{0}: $({1})\n", pi.name, pi.makename_ext);
360 catch (Exception e)
362 Console.WriteLine("EXCEPTION: {0}\n", e);
363 return "";
366 return MakefileBuilder.ToString();