source: trunk/qmake/generators/mac/metrowerks_xml.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

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