Diffstat (limited to 'qmake/generators/mac/metrowerks_xml.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | qmake/generators/mac/metrowerks_xml.cpp | 822 |
1 files changed, 822 insertions, 0 deletions
diff --git a/qmake/generators/mac/metrowerks_xml.cpp b/qmake/generators/mac/metrowerks_xml.cpp new file mode 100644 index 0000000..125749d --- a/dev/null +++ b/qmake/generators/mac/metrowerks_xml.cpp | |||
@@ -0,0 +1,822 @@ | |||
1 | /**************************************************************************** | ||
2 | ** $Id$ | ||
3 | ** | ||
4 | ** Definition of ________ class. | ||
5 | ** | ||
6 | ** Created : 970521 | ||
7 | ** | ||
8 | ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. | ||
9 | ** | ||
10 | ** This file is part of the network module of the Qt GUI Toolkit. | ||
11 | ** | ||
12 | ** This file may be distributed under the terms of the Q Public License | ||
13 | ** as defined by Trolltech AS of Norway and appearing in the file | ||
14 | ** LICENSE.QPL included in the packaging of this file. | ||
15 | ** | ||
16 | ** This file may be distributed and/or modified under the terms of the | ||
17 | ** GNU General Public License version 2 as published by the Free Software | ||
18 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
19 | ** packaging of this file. | ||
20 | ** | ||
21 | ** Licensees holding valid Qt Enterprise Edition licenses may use this | ||
22 | ** file in accordance with the Qt Commercial License Agreement provided | ||
23 | ** with the Software. | ||
24 | ** | ||
25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
27 | ** | ||
28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for | ||
29 | ** information about Qt Commercial License Agreements. | ||
30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. | ||
31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
32 | ** | ||
33 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
34 | ** not clear to you. | ||
35 | ** | ||
36 | **********************************************************************/ | ||
37 | |||
38 | #include "metrowerks_xml.h" | ||
39 | #include "option.h" | ||
40 | #include <qdir.h> | ||
41 | #include <qdict.h> | ||
42 | #include <qregexp.h> | ||
43 | #include <stdlib.h> | ||
44 | #include <time.h> | ||
45 | #ifdef Q_OS_MAC | ||
46 | #include <Carbon/Carbon.h> | ||
47 | #include <sys/types.h> | ||
48 | #include <sys/stat.h> | ||
49 | #endif | ||
50 | |||
51 | |||
52 | MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) | ||
53 | { | ||
54 | |||
55 | } | ||
56 | |||
57 | bool | ||
58 | MetrowerksMakefileGenerator::writeMakefile(QTextStream &t) | ||
59 | { | ||
60 | if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { | ||
61 | /* for now just dump, I need to generated an empty xml or something.. */ | ||
62 | fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", | ||
63 | var("QMAKE_FAILED_REQUIREMENTS").latin1()); | ||
64 | return TRUE; | ||
65 | } | ||
66 | |||
67 | if(project->first("TEMPLATE") == "app" || | ||
68 | project->first("TEMPLATE") == "lib") { | ||
69 | return writeMakeParts(t); | ||
70 | } | ||
71 | else if(project->first("TEMPLATE") == "subdirs") { | ||
72 | writeHeader(t); | ||
73 | qDebug("Not supported!"); | ||
74 | return TRUE; | ||
75 | } | ||
76 | return FALSE; | ||
77 | } | ||
78 | |||
79 | bool | ||
80 | MetrowerksMakefileGenerator::writeMakeParts(QTextStream &t) | ||
81 | { | ||
82 | //..grrr.. libs! | ||
83 | QStringList extra_objs; | ||
84 | bool do_libs = TRUE; | ||
85 | if(project->first("TEMPLATE") == "app") | ||
86 | extra_objs += project->variables()["QMAKE_CRT_OBJECTS"]; | ||
87 | else if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) | ||
88 | do_libs = FALSE; | ||
89 | if(do_libs) | ||
90 | extra_objs += project->variables()["QMAKE_LIBS"]; | ||
91 | for(QStringList::Iterator val_it = extra_objs.begin(); | ||
92 | val_it != extra_objs.end(); ++val_it) { | ||
93 | if((*val_it).startsWith("-L")) { | ||
94 | QString dir((*val_it).right((*val_it).length() - 2)); | ||
95 | fixEnvVariables(dir); | ||
96 | if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 && | ||
97 | project->variables()["INCLUDEPATH"].findIndex(dir) == -1) | ||
98 | project->variables()["INCLUDEPATH"].append(dir); | ||
99 | } else if((*val_it).startsWith("-l")) { | ||
100 | QString lib("lib" + (*val_it).right((*val_it).length() - 2) + "." + | ||
101 | project->first("QMAKE_EXTENSION_SHLIB")); | ||
102 | if(project->variables()["LIBRARIES"].findIndex(lib) == -1) | ||
103 | project->variables()["LIBRARIES"].append(lib); | ||
104 | } else | ||
105 | if((*val_it) == "-framework") { | ||
106 | ++val_it; | ||
107 | if(val_it == extra_objs.end()) | ||
108 | break; | ||
109 | QString frmwrk = (*val_it) + ".framework"; | ||
110 | if(project->variables()["FRAMEWORKS"].findIndex(frmwrk) == -1) | ||
111 | project->variables()["FRAMEWORKS"].append(frmwrk); | ||
112 | } else if((*val_it).left(1) != "-") { | ||
113 | QString lib=(*val_it); | ||
114 | int s = lib.findRev('/'); | ||
115 | if(s != -1) { | ||
116 | QString dir = lib.left(s); | ||
117 | lib = lib.right(lib.length() - s - 1); | ||
118 | fixEnvVariables(dir); | ||
119 | if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 && | ||
120 | project->variables()["INCLUDEPATH"].findIndex(dir) == -1) | ||
121 | project->variables()["INCLUDEPATH"].append(dir); | ||
122 | } | ||
123 | project->variables()["LIBRARIES"].append(lib); | ||
124 | } | ||
125 | } | ||
126 | //let metrowerks find the files & set the files to the type I expect | ||
127 | QDict<void> seen(293); | ||
128 | QString paths[] = { QString("SRCMOC"), QString("FORMS"), QString("UICDECLS"), | ||
129 | QString("UICIMPLS"), QString("SOURCES"),QString("HEADERS"), | ||
130 | QString::null }; | ||
131 | for(int y = 0; paths[y] != QString::null; y++) { | ||
132 | QStringList &l = project->variables()[paths[y]]; | ||
133 | for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { | ||
134 | //establish file types | ||
135 | seen.insert((*val_it), (void *)1); | ||
136 | createFork((*val_it)); //the file itself | ||
137 | QStringList &d = findDependencies((*val_it)); //depends | ||
138 | for(QStringList::Iterator dep_it = d.begin(); dep_it != d.end(); ++dep_it) { | ||
139 | if(!seen.find((*dep_it))) { | ||
140 | seen.insert((*dep_it), (void *)1); | ||
141 | createFork((*dep_it)); | ||
142 | } | ||
143 | } | ||
144 | //now chop it | ||
145 | int s = (*val_it).findRev('/'); | ||
146 | if(s != -1) { | ||
147 | QString dir = (*val_it).left(s); | ||
148 | (*val_it) = (*val_it).right((*val_it).length() - s - 1); | ||
149 | QString tmpd=dir, tmpv; | ||
150 | if(fixifyToMacPath(tmpd, tmpv)) { | ||
151 | bool add_in = TRUE; | ||
152 | QString deps[] = { QString("DEPENDPATH"), | ||
153 | QString("INCLUDEPATH"), QString::null }, | ||
154 | dd, dv; | ||
155 | for(int yy = 0; deps[yy] != QString::null; yy++) { | ||
156 | QStringList &l2 = project->variables()[deps[yy]]; | ||
157 | for(QStringList::Iterator val_it2 = l2.begin(); | ||
158 | val_it2 != l2.end(); ++val_it2) { | ||
159 | QString dd= (*val_it2), dv; | ||
160 | if(!fixifyToMacPath(dd, dv)) | ||
161 | continue; | ||
162 | if(dd == tmpd && tmpv == dv) { | ||
163 | add_in = FALSE; | ||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | if(add_in) | ||
169 | project->variables()["INCLUDEPATH"].append(dir); | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | //need a defines file | ||
175 | if(!project->isEmpty("DEFINES")) { | ||
176 | QString pre_pref = project->first("TARGET_STEM"); | ||
177 | if(project->first("TEMPLATE") == "lib") | ||
178 | pre_pref += project->isActiveConfig("staticlib") ? "_static" : "_shared"; | ||
179 | project->variables()["CODEWARRIOR_PREFIX_HEADER"].append(pre_pref + "_prefix.h"); | ||
180 | } | ||
181 | |||
182 | QString xmlfile = findTemplate(project->first("QMAKE_XML_TEMPLATE")); | ||
183 | QFile file(xmlfile); | ||
184 | if(!file.open(IO_ReadOnly )) { | ||
185 | fprintf(stderr, "Cannot open XML file: %s\n", | ||
186 | project->first("QMAKE_XML_TEMPLATE").latin1()); | ||
187 | return FALSE; | ||
188 | } | ||
189 | QTextStream xml(&file); | ||
190 | createFork(Option::output.name()); | ||
191 | |||
192 | int rep; | ||
193 | QString line; | ||
194 | while ( !xml.eof() ) { | ||
195 | line = xml.readLine(); | ||
196 | while((rep = line.find(QRegExp("\\$\\$[!a-zA-Z0-9_-]*"))) != -1) { | ||
197 | QString torep = line.mid(rep, line.find(QRegExp("[^\\$!a-zA-Z0-9_-]"), rep) - rep); | ||
198 | QString variable = torep.right(torep.length()-2); | ||
199 | |||
200 | t << line.left(rep); //output the left side | ||
201 | line = line.right(line.length() - (rep + torep.length())); //now past the variable | ||
202 | if(variable == "CODEWARRIOR_HEADERS" || variable == "CODEWARRIOR_SOURCES" || | ||
203 | variable == "CODEWARRIOR_LIBRARIES" || variable == "CODEWARRIOR_QPREPROCESS" || | ||
204 | variable == "CODEWARRIOR_QPREPROCESSOUT") { | ||
205 | QString outcmd=variable.right(variable.length() - variable.findRev('_') - 1); | ||
206 | QStringList args; | ||
207 | if(outcmd == "QPREPROCESS") | ||
208 | args << "UICS" << "MOCS"; | ||
209 | else if(outcmd == "QPREPROCESSOUT") | ||
210 | args << "SRCMOC" << "UICIMPLS" << "UICDELCS"; | ||
211 | else | ||
212 | args << outcmd; | ||
213 | for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { | ||
214 | QString arg = (*arit); | ||
215 | QString kind = "Text"; | ||
216 | if(arg == "LIBRARIES") | ||
217 | kind = "Library"; | ||
218 | if(!project->variables()[arg].isEmpty()) { | ||
219 | QStringList &list = project->variables()[arg]; | ||
220 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
221 | QString flag; | ||
222 | if(project->isActiveConfig("debug")) { | ||
223 | bool debug = TRUE; | ||
224 | if(outcmd == "QPREPROCESS") { | ||
225 | debug = FALSE; | ||
226 | } else { | ||
227 | for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { | ||
228 | if((*it).endsWith((*hit))) { | ||
229 | debug = FALSE; | ||
230 | break; | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | if(debug) | ||
235 | flag = "Debug"; | ||
236 | } | ||
237 | t << "\t\t\t\t<FILE>" << endl | ||
238 | << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl | ||
239 | << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl | ||
240 | << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl | ||
241 | << "\t\t\t\t\t<FILEKIND>" << kind << "</FILEKIND>" << endl | ||
242 | << "\t\t\t\t\t<FILEFLAGS>" << flag << "</FILEFLAGS>" << endl | ||
243 | << "\t\t\t\t</FILE>" << endl; | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | } else if(variable == "CODEWARRIOR_SOURCES_LINKORDER" || | ||
248 | variable == "CODEWARRIOR_HEADERS_LINKORDER" || | ||
249 | variable == "CODEWARRIOR_LIBRARIES_LINKORDER" || | ||
250 | variable == "CODEWARRIOR_QPREPROCESS_LINKORDER" || | ||
251 | variable == "CODEWARRIOR_QPREPROCESSOUT_LINKORDER") { | ||
252 | QString outcmd=variable.mid(variable.find('_')+1, | ||
253 | variable.findRev('_')-(variable.find('_')+1)); | ||
254 | QStringList args; | ||
255 | if(outcmd == "QPREPROCESS") | ||
256 | args << "UICS" << "MOCS"; | ||
257 | else if(outcmd == "QPREPROCESSOUT") | ||
258 | args << "SRCMOC" << "UICIMPLS" << "UICDELCS"; | ||
259 | else | ||
260 | args << outcmd; | ||
261 | for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { | ||
262 | QString arg = (*arit); | ||
263 | if(!project->variables()[arg].isEmpty()) { | ||
264 | QStringList &list = project->variables()[arg]; | ||
265 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
266 | t << "\t\t\t\t<FILEREF>" << endl | ||
267 | << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl | ||
268 | << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl | ||
269 | << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl | ||
270 | << "\t\t\t\t</FILEREF>" << endl; | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | } else if(variable == "CODEWARRIOR_HEADERS_GROUP" || | ||
275 | variable == "CODEWARRIOR_SOURCES_GROUP" || | ||
276 | variable == "CODEWARRIOR_LIBRARIES_GROUP" || | ||
277 | variable == "CODEWARRIOR_QPREPROCESS_GROUP" || | ||
278 | variable == "CODEWARRIOR_QPREPROCESSOUT_GROUP") { | ||
279 | QString outcmd = variable.mid(variable.find('_')+1, | ||
280 | variable.findRev('_')-(variable.find('_')+1)); | ||
281 | QStringList args; | ||
282 | if(outcmd == "QPREPROCESS") | ||
283 | args << "UICS" << "MOCS"; | ||
284 | else if(outcmd == "QPREPROCESSOUT") | ||
285 | args << "SRCMOC" << "UICIMPLS" << "UICDELCS"; | ||
286 | else | ||
287 | args << outcmd; | ||
288 | for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { | ||
289 | QString arg = (*arit); | ||
290 | if(!project->variables()[arg].isEmpty()) { | ||
291 | QStringList &list = project->variables()[arg]; | ||
292 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
293 | t << "\t\t\t\t<FILEREF>" << endl | ||
294 | << "\t\t\t\t\t<TARGETNAME>" << var("TARGET_STEM") << "</TARGETNAME>" | ||
295 | << endl | ||
296 | << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl | ||
297 | << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl | ||
298 | << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl | ||
299 | << "\t\t\t\t</FILEREF>" << endl; | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | } else if(variable == "CODEWARRIOR_FRAMEWORKS") { | ||
304 | if(!project->isEmpty("FRAMEWORKS")) { | ||
305 | QStringList &list = project->variables()["FRAMEWORKS"]; | ||
306 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
307 | t << "\t\t\t\t<FRAMEWORK>" << endl | ||
308 | << "\t\t\t\t\t<FILEREF>" << endl | ||
309 | << "\t\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl | ||
310 | << "\t\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl | ||
311 | << "\t\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl | ||
312 | << "\t\t\t\t\t</FILEREF>" << endl | ||
313 | << "\t\t\t\t</FRAMEWORK>" << endl; | ||
314 | } | ||
315 | } | ||
316 | } else if(variable == "CODEWARRIOR_DEPENDPATH" || variable == "CODEWARRIOR_INCLUDEPATH" || | ||
317 | variable == "CODEWARRIOR_FRAMEWORKPATH") { | ||
318 | QString arg=variable.right(variable.length()-variable.find('_')-1); | ||
319 | QStringList list; | ||
320 | if(arg == "INCLUDEPATH") { | ||
321 | list = project->variables()[arg]; | ||
322 | list << Option::mkfile::qmakespec; | ||
323 | list << QDir::current().currentDirPath(); | ||
324 | |||
325 | QStringList &l = project->variables()["QMAKE_LIBS_PATH"]; | ||
326 | for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { | ||
327 | QString p = (*val_it), v; | ||
328 | if(!fixifyToMacPath(p, v)) | ||
329 | continue; | ||
330 | |||
331 | t << "\t\t\t\t\t<SETTING>" << endl | ||
332 | << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl | ||
333 | << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>" | ||
334 | << "<VALUE>" << p << "</VALUE></SETTING>" << endl | ||
335 | << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl | ||
336 | << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING>" << endl | ||
337 | << "\t\t\t\t\t\t</SETTING>" << endl | ||
338 | << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING>" << endl | ||
339 | << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl | ||
340 | << "\t\t\t\t\t</SETTING>" << endl; | ||
341 | } | ||
342 | } else if(variable == "DEPENDPATH") { | ||
343 | QStringList &l = project->variables()[arg]; | ||
344 | for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) | ||
345 | { | ||
346 | //apparently tmake used colon separation... | ||
347 | QStringList damn = QStringList::split(':', (*val_it)); | ||
348 | if(!damn.isEmpty()) | ||
349 | list += damn; | ||
350 | else | ||
351 | list.append((*val_it)); | ||
352 | } | ||
353 | } else { | ||
354 | list = project->variables()[arg]; | ||
355 | } | ||
356 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
357 | QString p = (*it), v, recursive = "false", framework = "false"; | ||
358 | if(p.startsWith("recursive--")) { | ||
359 | p = p.right(p.length() - 11); | ||
360 | recursive = "true"; | ||
361 | } | ||
362 | if(!fixifyToMacPath(p, v)) | ||
363 | continue; | ||
364 | if(arg == "FRAMEWORKPATH") | ||
365 | framework = "true"; | ||
366 | |||
367 | t << "\t\t\t\t\t<SETTING>" << endl | ||
368 | << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl | ||
369 | << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>" | ||
370 | << "<VALUE>" << p << "</VALUE></SETTING>" << endl | ||
371 | << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl | ||
372 | << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << v << "</VALUE></SETTING>" << endl | ||
373 | << "\t\t\t\t\t\t</SETTING>" << endl | ||
374 | << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>" << recursive << "</VALUE></SETTING>" << endl | ||
375 | << "\t\t\t\t\t\t<SETTING><NAME>FrameworkPath</NAME><VALUE>" << framework << "</VALUE></SETTING>" << endl | ||
376 | << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl | ||
377 | << "\t\t\t\t\t</SETTING>" << endl; | ||
378 | } | ||
379 | } else if(variable == "CODEWARRIOR_WARNING" || variable == "!CODEWARRIOR_WARNING") { | ||
380 | bool b = ((!project->isActiveConfig("warn_off")) && | ||
381 | project->isActiveConfig("warn_on")); | ||
382 | if(variable.startsWith("!")) | ||
383 | b = !b; | ||
384 | t << (int)b; | ||
385 | } else if(variable == "CODEWARRIOR_TEMPLATE") { | ||
386 | if(project->first("TEMPLATE") == "app" ) { | ||
387 | t << "Executable"; | ||
388 | } else if(project->first("TEMPLATE") == "lib") { | ||
389 | if(project->isActiveConfig("staticlib")) | ||
390 | t << "Library"; | ||
391 | else | ||
392 | t << "SharedLibrary"; | ||
393 | } | ||
394 | } else if(variable == "CODEWARRIOR_OUTPUT_DIR") { | ||
395 | QString outdir = "{Project}/", volume; | ||
396 | if(!project->isEmpty("DESTDIR")) | ||
397 | outdir = project->first("DESTDIR"); | ||
398 | if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console")) | ||
399 | outdir += var("TARGET") + ".app/Contents/MacOS/"; | ||
400 | if(fixifyToMacPath(outdir, volume, FALSE)) { | ||
401 | t << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir << "</VALUE></SETTING>" | ||
402 | << endl | ||
403 | << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl | ||
404 | << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume << "</VALUE></SETTING>" | ||
405 | << endl; | ||
406 | } | ||
407 | } else if(variable == "CODEWARRIOR_PACKAGER_PANEL") { | ||
408 | if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console")) { | ||
409 | QString outdir = "{Project}/", volume; | ||
410 | if(!project->isEmpty("DESTDIR")) | ||
411 | outdir = project->first("DESTDIR"); | ||
412 | outdir += var("TARGET") + ".app"; | ||
413 | if(fixifyToMacPath(outdir, volume, FALSE)) { | ||
414 | t << "\t\t<SETTING><NAME>MWMacOSPackager_UsePackager</NAME>" | ||
415 | << "<VALUE>1</VALUE></SETTING>" << "\n" | ||
416 | << "\t\t<SETTING><NAME>MWMacOSPackager_FolderToPackage</NAME>" << "\n" | ||
417 | << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir | ||
418 | << "</VALUE></SETTING>" << "\n" | ||
419 | << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" | ||
420 | << "\n" | ||
421 | << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume | ||
422 | << "</VALUE></SETTING>" << "\n" | ||
423 | << "\t\t</SETTING>" << "\n" | ||
424 | << "\t\t<SETTING><NAME>MWMacOSPackager_CreateClassicAlias</NAME>" | ||
425 | << "<VALUE>0</VALUE></SETTING>" << "\n" | ||
426 | << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasMethod</NAME>" | ||
427 | << "<VALUE>UseTargetOutput</VALUE></SETTING>" << "\n" | ||
428 | << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasPath</NAME>" | ||
429 | << "<VALUE></VALUE></SETTING>" << "\n" | ||
430 | << "\t\t<SETTING><NAME>MWMacOSPackager_CreatePkgInfo</NAME>" | ||
431 | << "<VALUE>1</VALUE></SETTING>" << "\n" | ||
432 | << "\t\t<SETTING><NAME>MWMacOSPackager_PkgCreatorType</NAME>" | ||
433 | << "<VALUE>CUTE</VALUE></SETTING>" << "\n" | ||
434 | << "\t\t<SETTING><NAME>MWMacOSPackager_PkgFileType</NAME>" | ||
435 | << "<VALUE>APPL</VALUE></SETTING>" << endl; | ||
436 | } | ||
437 | } | ||
438 | } else if(variable == "CODEWARRIOR_FILETYPE") { | ||
439 | if(project->first("TEMPLATE") == "lib") | ||
440 | t << "MYDL"; | ||
441 | else | ||
442 | t << "MEXE"; | ||
443 | } else if(variable == "CODEWARRIOR_QTDIR") { | ||
444 | t << getenv("QTDIR"); | ||
445 | } else if(variable == "CODEWARRIOR_CACHEMODDATES") { | ||
446 | t << "true"; | ||
447 | } else { | ||
448 | t << var(variable); | ||
449 | } | ||
450 | } | ||
451 | t << line << endl; | ||
452 | } | ||
453 | t << endl; | ||
454 | file.close(); | ||
455 | |||
456 | if(mocAware()) { | ||
457 | QString mocs = project->first("MOCS"); | ||
458 | QFile mocfile(mocs); | ||
459 | if(!mocfile.open(IO_WriteOnly)) { | ||
460 | fprintf(stderr, "Cannot open MOCS file: %s\n", mocs.latin1()); | ||
461 | } else { | ||
462 | createFork(mocs); | ||
463 | QTextStream mocs(&mocfile); | ||
464 | QStringList &list = project->variables()["SRCMOC"]; | ||
465 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
466 | QString src = findMocSource((*it)); | ||
467 | if(src.findRev('/') != -1) | ||
468 | src = src.right(src.length() - src.findRev('/') - 1); | ||
469 | mocs << src << endl; | ||
470 | } | ||
471 | mocfile.close(); | ||
472 | } | ||
473 | } | ||
474 | |||
475 | if(!project->isEmpty("FORMS")) { | ||
476 | QString uics = project->first("UICS"); | ||
477 | QFile uicfile(uics); | ||
478 | if(!uicfile.open(IO_WriteOnly)) { | ||
479 | fprintf(stderr, "Cannot open UICS file: %s\n", uics.latin1()); | ||
480 | } else { | ||
481 | createFork(uics); | ||
482 | QTextStream uics(&uicfile); | ||
483 | QStringList &list = project->variables()["FORMS"]; | ||
484 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
485 | QString ui = (*it); | ||
486 | if(ui.findRev('/') != -1) | ||
487 | ui = ui.right(ui.length() - ui.findRev('/') - 1); | ||
488 | uics << ui << endl; | ||
489 | } | ||
490 | uicfile.close(); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | if(!project->isEmpty("CODEWARRIOR_PREFIX_HEADER")) { | ||
495 | QFile prefixfile(project->first("CODEWARRIOR_PREFIX_HEADER")); | ||
496 | if(!prefixfile.open(IO_WriteOnly)) { | ||
497 | fprintf(stderr, "Cannot open PREFIX file: %s\n", prefixfile.name().latin1()); | ||
498 | } else { | ||
499 | createFork(project->first("CODEWARRIOR_PREFIX_HEADER")); | ||
500 | QTextStream prefix(&prefixfile); | ||
501 | QStringList &list = project->variables()["DEFINES"]; | ||
502 | for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { | ||
503 | if((*it).find('=') != -1) { | ||
504 | int x = (*it).find('='); | ||
505 | prefix << "#define " << (*it).left(x) << " " << (*it).right((*it).length() - x - 1) << endl; | ||
506 | } else { | ||
507 | prefix << "#define " << (*it) << endl; | ||
508 | } | ||
509 | } | ||
510 | prefixfile.close(); | ||
511 | } | ||
512 | } | ||
513 | return TRUE; | ||
514 | } | ||
515 | |||
516 | |||
517 | |||
518 | void | ||
519 | MetrowerksMakefileGenerator::init() | ||
520 | { | ||
521 | if(init_flag) | ||
522 | return; | ||
523 | init_flag = TRUE; | ||
524 | |||
525 | if ( project->isEmpty("QMAKE_XML_TEMPLATE") ) | ||
526 | project->variables()["QMAKE_XML_TEMPLATE"].append("mwerkstmpl.xml"); | ||
527 | |||
528 | QStringList &configs = project->variables()["CONFIG"]; | ||
529 | if(project->isActiveConfig("qt")) { | ||
530 | if(configs.findIndex("moc")) configs.append("moc"); | ||
531 | if ( !( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") || | ||
532 | (project->first("TARGET") == "qt-mt") ) ) | ||
533 | project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; | ||
534 | if(configs.findIndex("moc")) | ||
535 | configs.append("moc"); | ||
536 | if ( !project->isActiveConfig("debug") ) | ||
537 | project->variables()["DEFINES"].append("QT_NO_DEBUG"); | ||
538 | } | ||
539 | |||
540 | //version handling | ||
541 | if(project->variables()["VERSION"].isEmpty()) | ||
542 | project->variables()["VERSION"].append("1.0." + | ||
543 | (project->isEmpty("VER_PAT") ? QString("0") : | ||
544 | project->first("VER_PAT")) ); | ||
545 | QStringList ver = QStringList::split('.', project->first("VERSION")); | ||
546 | ver << "0" << "0"; //make sure there are three | ||
547 | project->variables()["VER_MAJ"].append(ver[0]); | ||
548 | project->variables()["VER_MIN"].append(ver[1]); | ||
549 | project->variables()["VER_PAT"].append(ver[2]); | ||
550 | |||
551 | if( !project->isEmpty("LIBS") ) | ||
552 | project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; | ||
553 | if( project->variables()["QMAKE_EXTENSION_SHLIB"].isEmpty() ) | ||
554 | project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dylib" ); | ||
555 | |||
556 | if ( project->isActiveConfig("moc") ) { | ||
557 | QString mocfile = project->first("TARGET"); | ||
558 | if(project->first("TEMPLATE") == "lib") | ||
559 | mocfile += project->isActiveConfig("staticlib") ? "_static" : "_shared"; | ||
560 | project->variables()["MOCS"].append(mocfile + ".mocs"); | ||
561 | setMocAware(TRUE); | ||
562 | } | ||
563 | if(!project->isEmpty("FORMS")) { | ||
564 | QString uicfile = project->first("TARGET"); | ||
565 | if(project->first("TEMPLATE") == "lib") | ||
566 | uicfile += project->isActiveConfig("staticlib") ? "_static" : "_shared"; | ||
567 | project->variables()["UICS"].append(uicfile + ".uics"); | ||
568 | } | ||
569 | if(project->isEmpty("DESTDIR")) | ||
570 | project->variables()["DESTDIR"].append(QDir::currentDirPath()); | ||
571 | MakefileGenerator::init(); | ||
572 | |||
573 | if ( project->isActiveConfig("opengl") ) { | ||
574 | project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"]; | ||
575 | if ( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") || | ||
576 | (project->first("TARGET") == "qt-mt") ) | ||
577 | project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"]; | ||
578 | else | ||
579 | project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; | ||
580 | } | ||
581 | |||
582 | if(project->isActiveConfig("qt")) | ||
583 | project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; | ||
584 | if(project->isEmpty("FRAMEWORKPATH")) | ||
585 | project->variables()["FRAMEWORKPATH"].append("/System/Library/Frameworks/"); | ||
586 | |||
587 | //set the target up | ||
588 | project->variables()["TARGET_STEM"] = project->variables()["TARGET"]; | ||
589 | if(project->first("TEMPLATE") == "lib") { | ||
590 | if(project->isActiveConfig("staticlib")) | ||
591 | project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + ".lib"; | ||
592 | else | ||
593 | project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + "." + | ||
594 | project->first("QMAKE_EXTENSION_SHLIB"); | ||
595 | |||
596 | project->variables()["CODEWARRIOR_VERSION"].append(project->first("VER_MAJ") + | ||
597 | project->first("VER_MIN") + | ||
598 | project->first("VER_PAT")); | ||
599 | } else { | ||
600 | project->variables()["CODEWARRIOR_VERSION"].append("0"); | ||
601 | if(project->isEmpty("QMAKE_ENTRYPOINT")) | ||
602 | project->variables()["QMAKE_ENTRYPOINT"].append("start"); | ||
603 | project->variables()["CODEWARRIOR_ENTRYPOINT"].append( | ||
604 | project->first("QMAKE_ENTRYPOINT")); | ||
605 | } | ||
606 | } | ||
607 | |||
608 | |||
609 | QString | ||
610 | MetrowerksMakefileGenerator::findTemplate(QString file) | ||
611 | { | ||
612 | QString ret; | ||
613 | if(!QFile::exists(ret = file) && | ||
614 | !QFile::exists((ret = Option::mkfile::qmakespec + QDir::separator() + file)) && | ||
615 | !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/mac-mwerks/" + file)) && | ||
616 | !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file)))) | ||
617 | return ""; | ||
618 | return ret; | ||
619 | } | ||
620 | |||
621 | bool | ||
622 | MetrowerksMakefileGenerator::createFork(const QString &f) | ||
623 | { | ||
624 | #if defined(Q_OS_MACX) | ||
625 | FSRef fref; | ||
626 | FSSpec fileSpec; | ||
627 | if(QFile::exists(f)) { | ||
628 | mode_t perms = 0; | ||
629 | { | ||
630 | struct stat s; | ||
631 | stat(f.latin1(), &s); | ||
632 | if(!(s.st_mode & S_IWUSR)) { | ||
633 | perms = s.st_mode; | ||
634 | chmod(f.latin1(), perms | S_IWUSR); | ||
635 | } | ||
636 | } | ||
637 | FILE *o = fopen(f.latin1(), "a"); | ||
638 | if(!o) | ||
639 | return FALSE; | ||
640 | if(FSPathMakeRef((const UInt8 *)f.latin1(), &fref, NULL) == noErr) { | ||
641 | if(FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL) == noErr) | ||
642 | FSpCreateResFile(&fileSpec, 'CUTE', 'TEXT', smSystemScript); | ||
643 | else | ||
644 | qDebug("bogus %d", __LINE__); | ||
645 | } else | ||
646 | qDebug("bogus %d", __LINE__); | ||
647 | fclose(o); | ||
648 | if(perms) | ||
649 | chmod(f.latin1(), perms); | ||
650 | } | ||
651 | #else | ||
652 | Q_UNUSED(f) | ||
653 | #endif | ||
654 | return TRUE; | ||
655 | } | ||
656 | |||
657 | bool | ||
658 | MetrowerksMakefileGenerator::fixifyToMacPath(QString &p, QString &v, bool ) | ||
659 | { | ||
660 | v = "Absolute"; | ||
661 | if(p.find(':') != -1) //guess its macish already | ||
662 | return TRUE; | ||
663 | |||
664 | static QString st_volume; | ||
665 | if(st_volume.isEmpty()) { | ||
666 | st_volume = var("QMAKE_VOLUMENAME"); | ||
667 | #ifdef Q_OS_MAC | ||
668 | if(st_volume.isEmpty()) { | ||
669 | uchar foo[512]; | ||
670 | HVolumeParam pb; | ||
671 | memset(&pb, '\0', sizeof(pb)); | ||
672 | pb.ioVRefNum = 0; | ||
673 | pb.ioNamePtr = foo; | ||
674 | if(PBHGetVInfoSync((HParmBlkPtr)&pb) == noErr) { | ||
675 | int len = foo[0]; | ||
676 | memcpy(foo,foo+1, len); | ||
677 | foo[len] = '\0'; | ||
678 | st_volume = (char *)foo; | ||
679 | } | ||
680 | } | ||
681 | #endif | ||
682 | } | ||
683 | QString volume = st_volume; | ||
684 | |||
685 | fixEnvVariables(p); | ||
686 | if(p.startsWith("\"") && p.endsWith("\"")) | ||
687 | p = p.mid(1, p.length() - 2); | ||
688 | if(p.isEmpty()) | ||
689 | return FALSE; | ||
690 | if(!p.endsWith("/")) | ||
691 | p += "/"; | ||
692 | if(QDir::isRelativePath(p)) { | ||
693 | if(p.startsWith("{")) { | ||
694 | int eoc = p.find('}'); | ||
695 | if(eoc == -1) | ||
696 | return FALSE; | ||
697 | volume = p.mid(1, eoc - 1); | ||
698 | p = p.right(p.length() - eoc - 1); | ||
699 | } else { | ||
700 | QFileInfo fi(p); | ||
701 | if(fi.convertToAbs()) //strange | ||
702 | return FALSE; | ||
703 | p = fi.filePath(); | ||
704 | } | ||
705 | } | ||
706 | p = QDir::cleanDirPath(p); | ||
707 | if(!volume.isEmpty()) | ||
708 | v = volume; | ||
709 | p.replace("/", ":"); | ||
710 | if(p.right(1) != ":") | ||
711 | p += ':'; | ||
712 | return TRUE; | ||
713 | } | ||
714 | |||
715 | void | ||
716 | MetrowerksMakefileGenerator::processPrlFiles() | ||
717 | { | ||
718 | QPtrList<MakefileDependDir> libdirs; | ||
719 | libdirs.setAutoDelete(TRUE); | ||
720 | const QString lflags[] = { "QMAKE_LIBS", QString::null }; | ||
721 | for(int i = 0; !lflags[i].isNull(); i++) { | ||
722 | for(bool ret = FALSE; TRUE; ret = FALSE) { | ||
723 | QStringList l_out; | ||
724 | QStringList &l = project->variables()[lflags[i]]; | ||
725 | for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { | ||
726 | QString opt = (*it); | ||
727 | if(opt.startsWith("-")) { | ||
728 | if(opt.startsWith("-L")) { | ||
729 | QString r = opt.right(opt.length() - 2), l = r; | ||
730 | fixEnvVariables(l); | ||
731 | libdirs.append(new MakefileDependDir(r.replace( "\"", ""), | ||
732 | l.replace( "\"", ""))); | ||
733 | } else if(opt.left(2) == "-l") { | ||
734 | QString lib = opt.right(opt.length() - 2), prl; | ||
735 | for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { | ||
736 | prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext; | ||
737 | if(processPrlFile(prl)) { | ||
738 | if(prl.startsWith(mdd->local_dir)) | ||
739 | prl.replace(0, mdd->local_dir.length(), mdd->real_dir); | ||
740 | QRegExp reg("^.*lib(" + lib + "[^.]*)\\." + | ||
741 | project->first("QMAKE_EXTENSION_SHLIB") + "$"); | ||
742 | if(reg.exactMatch(prl)) | ||
743 | prl = "-l" + reg.cap(1); | ||
744 | opt = prl; | ||
745 | ret = TRUE; | ||
746 | break; | ||
747 | } | ||
748 | } | ||
749 | } else if(opt == "-framework") { | ||
750 | l_out.append(opt); | ||
751 | ++it; | ||
752 | opt = (*it); | ||
753 | QString prl = "/System/Library/Frameworks/" + opt + | ||
754 | ".framework/" + opt + Option::prl_ext; | ||
755 | if(processPrlFile(prl)) | ||
756 | ret = TRUE; | ||
757 | } | ||
758 | if(!opt.isEmpty()) | ||
759 | l_out.append(opt); | ||
760 | } else { | ||
761 | if(processPrlFile(opt)) | ||
762 | ret = TRUE; | ||
763 | if(!opt.isEmpty()) | ||
764 | l_out.append(opt); | ||
765 | } | ||
766 | } | ||
767 | if(ret) | ||
768 | l = l_out; | ||
769 | else | ||
770 | break; | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
775 | void | ||
776 | MetrowerksMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) | ||
777 | { | ||
778 | if(var == "QMAKE_PRL_LIBS") { | ||
779 | QStringList &out = project->variables()["QMAKE_LIBS"]; | ||
780 | for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { | ||
781 | bool append = TRUE; | ||
782 | if((*it).startsWith("-")) { | ||
783 | if((*it).startsWith("-l") || (*it).startsWith("-L")) { | ||
784 | append = out.findIndex((*it)) == -1; | ||
785 | } else if((*it).startsWith("-framework")) { | ||
786 | ++it; | ||
787 | for(QStringList::ConstIterator outit = out.begin(); | ||
788 | outit != out.end(); ++it) { | ||
789 | if((*outit) == "-framework") { | ||
790 | ++outit; | ||
791 | if((*outit) == (*it)) { | ||
792 | append = FALSE; | ||
793 | break; | ||
794 | } | ||
795 | } | ||
796 | } | ||
797 | } | ||
798 | } else if(QFile::exists((*it))) { | ||
799 | append = out.findIndex((*it)); | ||
800 | } | ||
801 | if(append) | ||
802 | out.append((*it)); | ||
803 | } | ||
804 | } else { | ||
805 | MakefileGenerator::processPrlVariable(var, l); | ||
806 | } | ||
807 | } | ||
808 | |||
809 | |||
810 | bool | ||
811 | MetrowerksMakefileGenerator::openOutput(QFile &file) const | ||
812 | { | ||
813 | QString outdir; | ||
814 | if(!file.name().isEmpty()) { | ||
815 | QFileInfo fi(file); | ||
816 | if(fi.isDir()) | ||
817 | outdir = file.name() + QDir::separator(); | ||
818 | } | ||
819 | if(!outdir.isEmpty() || file.name().isEmpty()) | ||
820 | file.setName(outdir + project->first("TARGET") + ".xml"); | ||
821 | return MakefileGenerator::openOutput(file); | ||
822 | } | ||