author | kergoth <kergoth> | 2002-11-01 00:10:42 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-11-01 00:10:42 (UTC) |
commit | 5042e3cf0d3514552769e441f5aad590c8eaf967 (patch) (unidiff) | |
tree | 4a5ea45f3519d981a172ab5275bf38c6fa778dec /qmake/generators/mac | |
parent | 108c1c753e74e989cc13923086996791428c9af4 (diff) | |
download | opie-5042e3cf0d3514552769e441f5aad590c8eaf967.zip opie-5042e3cf0d3514552769e441f5aad590c8eaf967.tar.gz opie-5042e3cf0d3514552769e441f5aad590c8eaf967.tar.bz2 |
Adding qmake in preperation for new build system
-rw-r--r-- | qmake/generators/mac/metrowerks_xml.cpp | 822 | ||||
-rw-r--r-- | qmake/generators/mac/metrowerks_xml.h | 69 | ||||
-rw-r--r-- | qmake/generators/mac/pbuilder_pbx.cpp | 983 | ||||
-rw-r--r-- | qmake/generators/mac/pbuilder_pbx.h | 68 |
4 files changed, 1942 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 | } | ||
diff --git a/qmake/generators/mac/metrowerks_xml.h b/qmake/generators/mac/metrowerks_xml.h new file mode 100644 index 0000000..ae3cfae --- a/dev/null +++ b/qmake/generators/mac/metrowerks_xml.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /**************************************************************************** | ||
2 | ** $Id$ | ||
3 | ** | ||
4 | ** Definition of ________ class. | ||
5 | ** | ||
6 | ** Created : 970521 | ||
7 | ** | ||
8 | ** Copyright (C) 1992-2000 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 | #ifndef __METROWERKSMAKE_H__ | ||
38 | #define __METROWERKSMAKE_H__ | ||
39 | |||
40 | #include "makefile.h" | ||
41 | |||
42 | class MetrowerksMakefileGenerator : public MakefileGenerator | ||
43 | { | ||
44 | bool createFork(const QString &f); | ||
45 | bool fixifyToMacPath(QString &c, QString &v, bool exists=TRUE); | ||
46 | |||
47 | bool init_flag; | ||
48 | |||
49 | bool writeMakeParts(QTextStream &); | ||
50 | bool writeSubDirs(QTextStream &); | ||
51 | |||
52 | bool writeMakefile(QTextStream &); | ||
53 | QString findTemplate(QString file); | ||
54 | void init(); | ||
55 | public: | ||
56 | MetrowerksMakefileGenerator(QMakeProject *p); | ||
57 | ~MetrowerksMakefileGenerator(); | ||
58 | |||
59 | bool openOutput(QFile &file) const; | ||
60 | protected: | ||
61 | virtual void processPrlFiles(); | ||
62 | virtual void processPrlVariable(const QString &var, const QStringList &l); | ||
63 | virtual bool doDepends() const { return FALSE; } //never necesary | ||
64 | }; | ||
65 | |||
66 | inline MetrowerksMakefileGenerator::~MetrowerksMakefileGenerator() | ||
67 | { } | ||
68 | |||
69 | #endif /* __METROWERKSMAKE_H__ */ | ||
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp new file mode 100644 index 0000000..8525058 --- a/dev/null +++ b/qmake/generators/mac/pbuilder_pbx.cpp | |||
@@ -0,0 +1,983 @@ | |||
1 | /**************************************************************************** | ||
2 | ** $Id$ | ||
3 | ** | ||
4 | ** Definition of ________ class. | ||
5 | ** | ||
6 | ** Created : 970521 | ||
7 | ** | ||
8 | ** Copyright (C) 1992-2000 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 "pbuilder_pbx.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_UNIX | ||
46 | # include <sys/types.h> | ||
47 | # include <sys/stat.h> | ||
48 | #endif | ||
49 | |||
50 | // Note: this is fairly hacky, but it does the job... | ||
51 | |||
52 | |||
53 | ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(QMakeProject *p) : UnixMakefileGenerator(p) | ||
54 | { | ||
55 | |||
56 | } | ||
57 | |||
58 | bool | ||
59 | ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t) | ||
60 | { | ||
61 | if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { | ||
62 | /* for now just dump, I need to generated an empty xml or something.. */ | ||
63 | fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", | ||
64 | var("QMAKE_FAILED_REQUIREMENTS").latin1()); | ||
65 | return TRUE; | ||
66 | } | ||
67 | |||
68 | project->variables()["MAKEFILE"].clear(); | ||
69 | project->variables()["MAKEFILE"].append("Makefile"); | ||
70 | if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { | ||
71 | return writeMakeParts(t); | ||
72 | } else if(project->first("TEMPLATE") == "subdirs") { | ||
73 | writeSubdirs(t, FALSE); | ||
74 | return TRUE; | ||
75 | } | ||
76 | return FALSE; | ||
77 | } | ||
78 | |||
79 | bool | ||
80 | ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) | ||
81 | { | ||
82 | int i; | ||
83 | QStringList tmp; | ||
84 | bool did_preprocess = FALSE; | ||
85 | |||
86 | //HEADER | ||
87 | t << "// !$*UTF8*$!" << "\n" | ||
88 | << "{" << "\n" | ||
89 | << "\t" << "archiveVersion = 1;" << "\n" | ||
90 | << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" | ||
91 | << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n" | ||
92 | << "\t" << "objects = {" << endl; | ||
93 | |||
94 | //MAKE QMAKE equivlant | ||
95 | if(!project->isActiveConfig("no_autoqmake") && project->projectFile() != "(stdin)") { | ||
96 | QString mkfile = pbx_dir + Option::dir_sep + "qt_makeqmake.mak"; | ||
97 | QFile mkf(mkfile); | ||
98 | if(mkf.open(IO_WriteOnly | IO_Translate)) { | ||
99 | debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); | ||
100 | QTextStream mkt(&mkf); | ||
101 | writeHeader(mkt); | ||
102 | mkt << "QMAKE = "<< | ||
103 | (project->isEmpty("QMAKE_QMAKE") ? QString("$(QTDIR)/bin/qmake") : | ||
104 | var("QMAKE_QMAKE")) << endl; | ||
105 | writeMakeQmake(mkt); | ||
106 | mkf.close(); | ||
107 | } | ||
108 | QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE"); | ||
109 | mkfile = fileFixify(mkfile, QDir::currentDirPath()); | ||
110 | project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); | ||
111 | t << "\t\t" << phase_key << " = {" << "\n" | ||
112 | << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" | ||
113 | << "\t\t\t" << "files = (" << "\n" | ||
114 | << "\t\t\t" << ");" << "\n" | ||
115 | << "\t\t\t" << "generatedFileNames = (" << "\n" | ||
116 | << "\t\t\t" << ");" << "\n" | ||
117 | << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" | ||
118 | << "\t\t\t" << "name = \"Qt Qmake\";" << "\n" | ||
119 | << "\t\t\t" << "neededFileNames = (" << "\n" | ||
120 | << "\t\t\t" << ");" << "\n" | ||
121 | << "\t\t\t" << "shellPath = /bin/sh;" << "\n" | ||
122 | << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() << | ||
123 | " -f " << mkfile << "\";" << "\n" | ||
124 | << "\t\t" << "};" << "\n"; | ||
125 | } | ||
126 | |||
127 | //DUMP SOURCES | ||
128 | QMap<QString, QStringList> groups; | ||
129 | QString srcs[] = { "SOURCES", "SRCMOC", "UICIMPLS", QString::null }; | ||
130 | for(i = 0; !srcs[i].isNull(); i++) { | ||
131 | tmp = project->variables()[srcs[i]]; | ||
132 | QStringList &src_list = project->variables()["QMAKE_PBX_" + srcs[i]]; | ||
133 | for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) { | ||
134 | QString file = fileFixify((*it)); | ||
135 | if(file.endsWith(Option::moc_ext)) | ||
136 | continue; | ||
137 | bool in_root = TRUE; | ||
138 | QString src_key = keyFor(file); | ||
139 | if(!project->isActiveConfig("flat")) { | ||
140 | QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE); | ||
141 | if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) { | ||
142 | QString last_grp("QMAKE_PBX_" + srcs[i] + "_HEIR_GROUP"); | ||
143 | QStringList dirs = QStringList::split(Option::dir_sep, flat_file); | ||
144 | dirs.pop_back(); //remove the file portion as it will be added via src_key | ||
145 | for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { | ||
146 | QString new_grp(last_grp + Option::dir_sep + (*dir_it)), | ||
147 | new_grp_key(keyFor(new_grp)), last_grp_key(keyFor(last_grp)); | ||
148 | if(dir_it == dirs.begin()) { | ||
149 | if(!groups.contains(new_grp)) | ||
150 | project->variables()["QMAKE_PBX_" + srcs[i]].append(new_grp_key); | ||
151 | } else { | ||
152 | groups[last_grp] += new_grp_key; | ||
153 | } | ||
154 | last_grp = new_grp; | ||
155 | } | ||
156 | groups[last_grp] += src_key; | ||
157 | in_root = FALSE; | ||
158 | } | ||
159 | } | ||
160 | if(in_root) | ||
161 | src_list.append(src_key); | ||
162 | //source reference | ||
163 | t << "\t\t" << src_key << " = {" << "\n" | ||
164 | << "\t\t\t" << "isa = PBXFileReference;" << "\n" | ||
165 | << "\t\t\t" << "path = \"" << file << "\";" << "\n" | ||
166 | << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n" | ||
167 | << "\t\t" << "};" << "\n"; | ||
168 | //build reference | ||
169 | QString obj_key = file + ".o"; | ||
170 | obj_key = keyFor(obj_key); | ||
171 | t << "\t\t" << obj_key << " = {" << "\n" | ||
172 | << "\t\t\t" << "fileRef = " << src_key << ";" << "\n" | ||
173 | << "\t\t\t" << "isa = PBXBuildFile;" << "\n" | ||
174 | << "\t\t\t" << "settings = {" << "\n" | ||
175 | << "\t\t\t\t" << "ATTRIBUTES = (" << "\n" | ||
176 | << "\t\t\t\t" << ");" << "\n" | ||
177 | << "\t\t\t" << "};" << "\n" | ||
178 | << "\t\t" << "};" << "\n"; | ||
179 | project->variables()["QMAKE_PBX_OBJ"].append(obj_key); | ||
180 | } | ||
181 | if(!src_list.isEmpty()) { | ||
182 | QString grp; | ||
183 | if(srcs[i] == "SOURCES") { | ||
184 | if(project->first("TEMPLATE") == "app" && !project->isEmpty("RC_FILE")) { //Icon | ||
185 | QString icns_file = keyFor("ICNS_FILE"); | ||
186 | src_list.append(icns_file); | ||
187 | t << "\t\t" << icns_file << " = {" << "\n" | ||
188 | << "\t\t\t" << "isa = PBXFileReference;" << "\n" | ||
189 | << "\t\t\t" << "path = \"" << project->first("RC_FILE") << "\";" << "\n" | ||
190 | << "\t\t\t" << "refType = " << reftypeForFile(project->first("RC_FILE")) << ";" << "\n" | ||
191 | << "\t\t" << "};" << "\n"; | ||
192 | t << "\t\t" << keyFor("ICNS_FILE_REFERENCE") << " = {" << "\n" | ||
193 | << "\t\t\t" << "fileRef = " << icns_file << ";" << "\n" | ||
194 | << "\t\t\t" << "isa = PBXBuildFile;" << "\n" | ||
195 | << "\t\t\t" << "settings = {" << "\n" | ||
196 | << "\t\t\t" << "};" << "\n" | ||
197 | << "\t\t" << "};" << "\n"; | ||
198 | } | ||
199 | grp = "Sources"; | ||
200 | } else if(srcs[i] == "SRCMOC") { | ||
201 | grp = "Mocables"; | ||
202 | } else if(srcs[i] == "UICIMPLS") { | ||
203 | grp = "UICables"; | ||
204 | } | ||
205 | QString grp_key = keyFor(grp); | ||
206 | project->variables()["QMAKE_PBX_GROUPS"].append(grp_key); | ||
207 | t << "\t\t" << grp_key << " = {" << "\n" | ||
208 | << "\t\t\t" << "children = (" << "\n" | ||
209 | << varGlue("QMAKE_PBX_" + srcs[i], "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
210 | << "\t\t\t" << ");" << "\n" | ||
211 | << "\t\t\t" << "isa = PBXGroup;" << "\n" | ||
212 | << "\t\t\t" << "name = " << grp << ";" << "\n" | ||
213 | << "\t\t\t" << "refType = 4;" << "\n" | ||
214 | << "\t\t" << "};" << "\n"; | ||
215 | } | ||
216 | } | ||
217 | for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); | ||
218 | grp_it != groups.end(); ++grp_it) { | ||
219 | t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n" | ||
220 | << "\t\t\t" << "isa = PBXGroup;" << "\n" | ||
221 | << "\t\t\t" << "children = (" << "\n" | ||
222 | << valGlue(grp_it.data(), "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
223 | << "\t\t\t" << ");" << "\n" | ||
224 | << "\t\t\t" << "name = \"" << grp_it.key().section(Option::dir_sep, -1) << "\";" << "\n" | ||
225 | << "\t\t\t" << "refType = 4;" << "\n" | ||
226 | << "\t\t" << "};" << "\n"; | ||
227 | } | ||
228 | |||
229 | //PREPROCESS BUILDPHASE (just a makefile) | ||
230 | if(!project->isEmpty("UICIMPLS") || !project->isEmpty("SRCMOC") || | ||
231 | !project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) { | ||
232 | QString mkfile = pbx_dir + Option::dir_sep + "qt_preprocess.mak"; | ||
233 | QFile mkf(mkfile); | ||
234 | if(mkf.open(IO_WriteOnly | IO_Translate)) { | ||
235 | did_preprocess = TRUE; | ||
236 | debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); | ||
237 | QTextStream mkt(&mkf); | ||
238 | writeHeader(mkt); | ||
239 | mkt << "MOC = " << var("QMAKE_MOC") << endl; | ||
240 | mkt << "UIC = " << var("QMAKE_UIC") << endl; | ||
241 | mkt << "LEX = " << var("QMAKE_LEX") << endl; | ||
242 | mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl; | ||
243 | mkt << "YACC = " << var("QMAKE_YACC") << endl; | ||
244 | mkt << "YACCFLAGS = " << var("QMAKE_YACCFLAGS") << endl; | ||
245 | mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; | ||
246 | mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl; | ||
247 | mkt << "FORMS = " << varList("UICIMPLS") << endl; | ||
248 | mkt << "MOCS = " << varList("SRCMOC") << endl; | ||
249 | mkt << "PARSERS ="; | ||
250 | if(!project->isEmpty("YACCSOURCES")) { | ||
251 | QStringList &yaccs = project->variables()["YACCSOURCES"]; | ||
252 | for(QStringList::Iterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) { | ||
253 | QFileInfo fi((*yit)); | ||
254 | mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE) | ||
255 | << Option::yacc_mod << Option::cpp_ext.first(); | ||
256 | } | ||
257 | } | ||
258 | if(!project->isEmpty("LEXSOURCES")) { | ||
259 | QStringList &lexs = project->variables()["LEXSOURCES"]; | ||
260 | for(QStringList::Iterator lit = lexs.begin(); lit != lexs.end(); ++lit) { | ||
261 | QFileInfo fi((*lit)); | ||
262 | mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE) | ||
263 | << Option::lex_mod << Option::cpp_ext.first(); | ||
264 | } | ||
265 | } | ||
266 | mkt << "\n"; | ||
267 | mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS)" << endl; | ||
268 | mkt << "preprocess_clean: mocclean uiclean parser_clean" << endl << endl; | ||
269 | mkt << "mocclean:" << "\n"; | ||
270 | if(!project->isEmpty("SRCMOC")) | ||
271 | mkt << "\t-rm -f $(MOCS)" << "\n"; | ||
272 | mkt << "uiclean:" << "\n"; | ||
273 | if(!project->isEmpty("UICIMPLS")) | ||
274 | mkt << "\t-rm -f $(FORMS)" << "\n"; | ||
275 | mkt << "parser_clean:" << "\n"; | ||
276 | if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) | ||
277 | mkt << "\t-rm -f $(PARSERS)" << "\n"; | ||
278 | writeUicSrc(mkt, "FORMS"); | ||
279 | writeMocSrc(mkt, "HEADERS"); | ||
280 | writeMocSrc(mkt, "SOURCES"); | ||
281 | writeMocSrc(mkt, "UICDECLS"); | ||
282 | writeYaccSrc(mkt, "YACCSOURCES"); | ||
283 | writeLexSrc(mkt, "LEXSOURCES"); | ||
284 | mkf.close(); | ||
285 | } | ||
286 | QString target_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET"); | ||
287 | mkfile = fileFixify(mkfile, QDir::currentDirPath()); | ||
288 | t << "\t\t" << target_key << " = {" << "\n" | ||
289 | << "\t\t\t" << "buildArgumentsString = \"-f " << mkfile << "\";" << "\n" | ||
290 | << "\t\t\t" << "buildPhases = (" << "\n" | ||
291 | << "\t\t\t" << ");" << "\n" | ||
292 | << "\t\t\t" << "buildSettings = {" << "\n" | ||
293 | << "\t\t\t" << "};" << "\n" | ||
294 | << "\t\t\t" << "buildToolPath = \"/usr/bin/gnumake\";"<< "\n" | ||
295 | << "\t\t\t" << "buildWorkingDirectory = \"" << QDir::currentDirPath() << "\";" << "\n" | ||
296 | << "\t\t\t" << "dependencies = (" << "\n" | ||
297 | << "\t\t\t" << ");" << "\n" | ||
298 | << "\t\t\t" << "isa = PBXLegacyTarget;" << "\n" | ||
299 | << "\t\t\t" << "name = QtPreprocessors;" << "\n" | ||
300 | << "\t\t\t" << "productName = QtPreprocessors;" << "\n" | ||
301 | << "\t\t\t" << "settingsToExpand = 6;" << "\n" | ||
302 | << "\t\t\t" << "settingsToPassInEnvironment = 287;" << "\n" | ||
303 | << "\t\t\t" << "settingsToPassOnCommandLine = 280;" << "\n" | ||
304 | << "\t\t\t" << "shouldsUseHeadermap = 0;" << "\n" | ||
305 | << "\t\t" << "};" << "\n"; | ||
306 | |||
307 | QString target_depend_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET_DEPEND"); | ||
308 | project->variables()["QMAKE_PBX_TARGETDEPENDS"].append(target_depend_key); | ||
309 | t << "\t\t" << target_depend_key << " = {" << "\n" | ||
310 | << "\t\t\t" << "isa = PBXTargetDependency;" << "\n" | ||
311 | << "\t\t\t" << "target = " << target_key << ";" << "\n" | ||
312 | << "\t\t" << "};" << "\n"; | ||
313 | } | ||
314 | //SOURCE BUILDPHASE | ||
315 | if(!project->isEmpty("QMAKE_PBX_OBJ")) { | ||
316 | QString grp = "Build Sources", key = keyFor(grp); | ||
317 | project->variables()["QMAKE_PBX_BUILDPHASES"].append(key); | ||
318 | t << "\t\t" << key << " = {" << "\n" | ||
319 | << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" | ||
320 | << "\t\t\t" << "files = (" << "\n" | ||
321 | << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
322 | << "\t\t\t" << ");" << "\n" | ||
323 | << "\t\t\t" << "isa = PBXSourcesBuildPhase;" << "\n" | ||
324 | << "\t\t\t" << "name = \"" << grp << "\";" << "\n" | ||
325 | << "\t\t" << "};" << "\n"; | ||
326 | } | ||
327 | |||
328 | if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES | ||
329 | QStringList &libdirs = project->variables()["QMAKE_PBX_LIBPATHS"]; | ||
330 | QString libs[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; | ||
331 | for(i = 0; !libs[i].isNull(); i++) { | ||
332 | tmp = project->variables()[libs[i]]; | ||
333 | for(QStringList::Iterator it = tmp.begin(); it != tmp.end();) { | ||
334 | bool remove = FALSE; | ||
335 | QString library, name, opt = (*it).stripWhiteSpace(); | ||
336 | if(opt.startsWith("-L")) { | ||
337 | QString r = opt.right(opt.length() - 2); | ||
338 | fixEnvVariables(r); | ||
339 | libdirs.append(r); | ||
340 | } else if(opt.startsWith("-l")) { | ||
341 | name = opt.right(opt.length() - 2); | ||
342 | QString lib("lib" + name); | ||
343 | for(QStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) { | ||
344 | if(project->isActiveConfig("link_prl")) { | ||
345 | /* This isn't real nice, but it is real usefull. This looks in a prl | ||
346 | for what the library will ultimately be called so we can stick it | ||
347 | in the ProjectFile. If the prl format ever changes (not likely) then | ||
348 | this will not really work. However, more concerning is that it will | ||
349 | encode the version number in the Project file which might be a bad | ||
350 | things in days to come? --Sam | ||
351 | */ | ||
352 | QString prl_file = (*lit) + Option::dir_sep + lib + Option::prl_ext; | ||
353 | if(QFile::exists(prl_file)) { | ||
354 | QMakeProject proj; | ||
355 | if(proj.read(prl_file, QDir::currentDirPath())) { | ||
356 | if(!proj.isEmpty("QMAKE_PRL_TARGET")) { | ||
357 | library = (*lit) + Option::dir_sep + proj.first("QMAKE_PRL_TARGET"); | ||
358 | debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)", | ||
359 | opt.latin1(), prl_file.latin1(), library.latin1()); | ||
360 | remove = TRUE; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | } | ||
365 | } | ||
366 | if(!remove) { | ||
367 | QString extns[] = { ".dylib", ".so", ".a", QString::null }; | ||
368 | for(int n = 0; !remove && !extns[n].isNull(); n++) { | ||
369 | QString tmp = (*lit) + Option::dir_sep + lib + extns[n]; | ||
370 | if(QFile::exists(tmp)) { | ||
371 | library = tmp; | ||
372 | debug_msg(1, "pbuilder: Found library (%s) via %s", | ||
373 | opt.latin1(), library.latin1()); | ||
374 | remove = TRUE; | ||
375 | } | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | } else if(opt == "-framework") { | ||
380 | ++it; | ||
381 | if(it == tmp.end()) | ||
382 | break; | ||
383 | QStringList &fdirs = project->variables()["QMAKE_FRAMEWORKDIR"]; | ||
384 | if(fdirs.isEmpty()) | ||
385 | fdirs.append("/System/Library/Frameworks/"); | ||
386 | for(QStringList::Iterator fit = fdirs.begin(); fit != fdirs.end(); ++fit) { | ||
387 | if(QFile::exists((*fit) + QDir::separator() + (*it) + ".framework")) { | ||
388 | --it; | ||
389 | it = tmp.remove(it); | ||
390 | remove = TRUE; | ||
391 | library = (*fit) + Option::dir_sep + (*it) + ".framework"; | ||
392 | break; | ||
393 | } | ||
394 | } | ||
395 | } else if(opt.left(1) != "-") { | ||
396 | remove = TRUE; | ||
397 | library = opt; | ||
398 | } | ||
399 | if(!library.isEmpty()) { | ||
400 | if(name.isEmpty()) { | ||
401 | int slsh = library.findRev(Option::dir_sep); | ||
402 | if(slsh != -1) | ||
403 | name = library.right(library.length() - slsh - 1); | ||
404 | } | ||
405 | library = fileFixify(library); | ||
406 | QString key = keyFor(library); | ||
407 | bool is_frmwrk = (library.endsWith(".framework")); | ||
408 | t << "\t\t" << key << " = {" << "\n" | ||
409 | << "\t\t\t" << "isa = " << (is_frmwrk ? "PBXFrameworkReference" : "PBXFileReference") << ";" << "\n" | ||
410 | << "\t\t\t" << "name = \"" << name << "\";" << "\n" | ||
411 | << "\t\t\t" << "path = \"" << library << "\";" << "\n" | ||
412 | << "\t\t\t" << "refType = " << reftypeForFile(library) << ";" << "\n" | ||
413 | << "\t\t" << "};" << "\n"; | ||
414 | project->variables()["QMAKE_PBX_LIBRARIES"].append(key); | ||
415 | QString obj_key = library + ".o"; | ||
416 | obj_key = keyFor(obj_key); | ||
417 | t << "\t\t" << obj_key << " = {" << "\n" | ||
418 | << "\t\t\t" << "fileRef = " << key << ";" << "\n" | ||
419 | << "\t\t\t" << "isa = PBXBuildFile;" << "\n" | ||
420 | << "\t\t\t" << "settings = {" << "\n" | ||
421 | << "\t\t\t" << "};" << "\n" | ||
422 | << "\t\t" << "};" << "\n"; | ||
423 | project->variables()["QMAKE_PBX_BUILD_LIBRARIES"].append(obj_key); | ||
424 | } | ||
425 | if(remove) | ||
426 | it = tmp.remove(it); | ||
427 | else | ||
428 | ++it; | ||
429 | } | ||
430 | project->variables()[libs[i]] = tmp; | ||
431 | } | ||
432 | } | ||
433 | //SUBLIBS BUILDPHASE (just another makefile) | ||
434 | if(!project->isEmpty("SUBLIBS")) { | ||
435 | QString mkfile = pbx_dir + Option::dir_sep + "qt_sublibs.mak"; | ||
436 | QFile mkf(mkfile); | ||
437 | if(mkf.open(IO_WriteOnly | IO_Translate)) { | ||
438 | debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); | ||
439 | QTextStream mkt(&mkf); | ||
440 | writeHeader(mkt); | ||
441 | mkt << "SUBLIBS= "; | ||
442 | tmp = project->variables()["SUBLIBS"]; | ||
443 | QStringList::Iterator it; | ||
444 | for(it = tmp.begin(); it != tmp.end(); ++it) | ||
445 | t << "tmp/lib" << (*it) << ".a "; | ||
446 | t << endl << endl; | ||
447 | mkt << "sublibs: $(SUBLIBS)" << endl << endl; | ||
448 | tmp = project->variables()["SUBLIBS"]; | ||
449 | for(it = tmp.begin(); it != tmp.end(); ++it) | ||
450 | t << "tmp/lib" << (*it) << ".a" << ":\n\t" | ||
451 | << var(QString("MAKELIB") + (*it)) << endl << endl; | ||
452 | mkf.close(); | ||
453 | } | ||
454 | QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE"); | ||
455 | mkfile = fileFixify(mkfile, QDir::currentDirPath()); | ||
456 | project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); | ||
457 | t << "\t\t" << phase_key << " = {" << "\n" | ||
458 | << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" | ||
459 | << "\t\t\t" << "files = (" << "\n" | ||
460 | << "\t\t\t" << ");" << "\n" | ||
461 | << "\t\t\t" << "generatedFileNames = (" << "\n" | ||
462 | << "\t\t\t" << ");" << "\n" | ||
463 | << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" | ||
464 | << "\t\t\t" << "name = \"Qt Sublibs\";" << "\n" | ||
465 | << "\t\t\t" << "neededFileNames = (" << "\n" | ||
466 | << "\t\t\t" << ");" << "\n" | ||
467 | << "\t\t\t" << "shellPath = /bin/sh;" << "\n" | ||
468 | << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() << | ||
469 | " -f " << mkfile << "\";" << "\n" | ||
470 | << "\t\t" << "};" << "\n"; | ||
471 | } | ||
472 | //LIBRARY BUILDPHASE | ||
473 | if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) { | ||
474 | tmp = project->variables()["QMAKE_PBX_LIBRARIES"]; | ||
475 | if(!tmp.isEmpty()) { | ||
476 | QString grp("External Frameworks and Libraries"), key = keyFor(grp); | ||
477 | project->variables()["QMAKE_PBX_GROUPS"].append(key); | ||
478 | t << "\t\t" << key << " = {" << "\n" | ||
479 | << "\t\t\t" << "children = (" << "\n" | ||
480 | << varGlue("QMAKE_PBX_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
481 | << "\t\t\t" << ");" << "\n" | ||
482 | << "\t\t\t" << "isa = PBXGroup;" << "\n" | ||
483 | << "\t\t\t" << "name = \"" << grp << "\"" << ";" << "\n" | ||
484 | << "\t\t\t" << "path = \"\";" << "\n" | ||
485 | << "\t\t\t" << "refType = 4;" << "\n" | ||
486 | << "\t\t" << "};" << "\n"; | ||
487 | } | ||
488 | } | ||
489 | { | ||
490 | QString grp("Frameworks & Libraries"), key = keyFor(grp); | ||
491 | project->variables()["QMAKE_PBX_BUILDPHASES"].append(key); | ||
492 | t << "\t\t" << key << " = {" << "\n" | ||
493 | << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" | ||
494 | << "\t\t\t" << "files = (" << "\n" | ||
495 | << varGlue("QMAKE_PBX_BUILD_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
496 | << "\t\t\t" << ");" << "\n" | ||
497 | << "\t\t\t" << "isa = PBXFrameworksBuildPhase;" << "\n" | ||
498 | << "\t\t\t" << "name = \"" << grp << "\";" << "\n" | ||
499 | << "\t\t" << "};" << "\n"; | ||
500 | } | ||
501 | if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console") && | ||
502 | project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES | ||
503 | QString grp("Bundle Resources"), key = keyFor(grp); | ||
504 | project->variables()["QMAKE_PBX_BUILDPHASES"].append(key); | ||
505 | t << "\t\t" << key << " = {" << "\n" | ||
506 | << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" | ||
507 | << "\t\t\t" << "files = (" << "\n" | ||
508 | << (!project->isEmpty("RC_FILE") ? keyFor("ICNS_FILE_REFERENCE") : QString("")) | ||
509 | << "\t\t\t" << ");" << "\n" | ||
510 | << "\t\t\t" << "isa = PBXResourcesBuildPhase;" << "\n" | ||
511 | << "\t\t\t" << "name = \"" << grp << "\";" << "\n" | ||
512 | << "\t\t" << "};" << "\n"; | ||
513 | } | ||
514 | |||
515 | //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER | ||
516 | //PRODUCTS | ||
517 | { | ||
518 | QString grp("Products"), key = keyFor(grp); | ||
519 | project->variables()["QMAKE_PBX_GROUPS"].append(key); | ||
520 | t << "\t\t" << key << " = {" << "\n" | ||
521 | << "\t\t\t" << "children = (" << "\n" | ||
522 | << "\t\t\t\t" << keyFor("QMAKE_PBX_REFERENCE") << "\n" | ||
523 | << "\t\t\t" << ");" << "\n" | ||
524 | << "\t\t\t" << "isa = PBXGroup;" << "\n" | ||
525 | << "\t\t\t" << "name = Products;" << "\n" | ||
526 | << "\t\t\t" << "refType = 4;" << "\n" | ||
527 | << "\t\t" << "};" << "\n"; | ||
528 | } | ||
529 | { //INSTALL BUILDPHASE (sh script) | ||
530 | QString targ = project->first("TARGET"); | ||
531 | if(project->first("TEMPLATE") == "app" || | ||
532 | (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && | ||
533 | project->isActiveConfig("frameworklib"))) | ||
534 | targ = project->first("QMAKE_ORIG_TARGET"); | ||
535 | int slsh = targ.findRev(Option::dir_sep); | ||
536 | if(slsh != -1) | ||
537 | targ = targ.right(targ.length() - slsh - 1); | ||
538 | fixEnvVariables(targ); | ||
539 | QStringList links; | ||
540 | if(project->first("TEMPLATE") == "app") { | ||
541 | if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) | ||
542 | targ += ".app"; | ||
543 | } else if(!project->isActiveConfig("staticlib") && | ||
544 | !project->isActiveConfig("frameworklib")) { | ||
545 | QString li[] = { "TARGET_", "TARGET_x", "TARGET_x.y", QString::null }; | ||
546 | for(int n = 0; !li[n].isNull(); n++) { | ||
547 | QString t = project->first(li[n]); | ||
548 | slsh = t.findRev(Option::dir_sep); | ||
549 | if(slsh != -1) | ||
550 | t = t.right(t.length() - slsh); | ||
551 | fixEnvVariables(t); | ||
552 | links << t; | ||
553 | } | ||
554 | } | ||
555 | QString script = pbx_dir + Option::dir_sep + "qt_install.sh"; | ||
556 | QFile shf(script); | ||
557 | if(shf.open(IO_WriteOnly | IO_Translate)) { | ||
558 | debug_msg(1, "pbuilder: Creating file: %s", script.latin1()); | ||
559 | QString targ = project->first("QMAKE_ORIG_TARGET"), cpflags; | ||
560 | if(project->first("TEMPLATE") == "app") { | ||
561 | targ = project->first("TARGET"); | ||
562 | if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { | ||
563 | targ += ".app"; | ||
564 | cpflags += "-r "; | ||
565 | } | ||
566 | } else if(!project->isActiveConfig("frameworklib")) { | ||
567 | if(project->isActiveConfig("staticlib")) | ||
568 | targ = project->first("TARGET"); | ||
569 | else | ||
570 | targ = project->first("TARGET_"); | ||
571 | int slsh = targ.findRev(Option::dir_sep); | ||
572 | if(slsh != -1) | ||
573 | targ = targ.right(targ.length() - slsh - 1); | ||
574 | } | ||
575 | QTextStream sht(&shf); | ||
576 | QString dstdir = project->first("DESTDIR"); | ||
577 | fixEnvVariables(dstdir); | ||
578 | |||
579 | sht << "#!/bin/sh" << endl; | ||
580 | //copy the actual target | ||
581 | sht << "OUT_TARG=\"" << targ << "\"\n" | ||
582 | << "[ -z \"$BUILD_ROOT\" ] || OUT_TARG=\"${BUILD_ROOT}/${OUT_TARG}\"" << endl; | ||
583 | sht << "[ \"$OUT_TARG\" = \"" | ||
584 | << (dstdir.isEmpty() ? QDir::currentDirPath() + QDir::separator(): dstdir) << targ << "\" ] || " | ||
585 | << "[ \"$OUT_TARG\" = \"" << targ << "\" ] || " | ||
586 | << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << endl; | ||
587 | //rename as a framework | ||
588 | if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib")) | ||
589 | sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << targ << "\"" << endl; | ||
590 | //create all the version symlinks (just to be like unixmake) | ||
591 | for(QStringList::Iterator it = links.begin(); it != links.end(); ++it) { | ||
592 | if(targ != (*it)) | ||
593 | sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << (*it) << "\"" << endl; | ||
594 | } | ||
595 | shf.close(); | ||
596 | #ifdef Q_OS_UNIX | ||
597 | chmod(script.latin1(), S_IRWXU | S_IRWXG); | ||
598 | #endif | ||
599 | QString phase_key = keyFor("QMAKE_PBX_INSTALL_BUILDPHASE"); | ||
600 | script = fileFixify(script, QDir::currentDirPath()); | ||
601 | project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); | ||
602 | t << "\t\t" << phase_key << " = {" << "\n" | ||
603 | << "\t\t\t" << "buildActionMask = 8;" << "\n" //only on install! | ||
604 | << "\t\t\t" << "files = (" << "\n" | ||
605 | << "\t\t\t" << ");" << "\n" | ||
606 | << "\t\t\t" << "generatedFileNames = (" << "\n" | ||
607 | << "\t\t\t" << ");" << "\n" | ||
608 | << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" | ||
609 | << "\t\t\t" << "name = \"Qt Install\";" << "\n" | ||
610 | << "\t\t\t" << "neededFileNames = (" << "\n" | ||
611 | << "\t\t\t" << ");" << "\n" | ||
612 | << "\t\t\t" << "shellPath = /bin/sh;" << "\n" | ||
613 | << "\t\t\t" << "shellScript = \"" << script << "\";" << "\n" | ||
614 | << "\t\t" << "};" << "\n"; | ||
615 | } | ||
616 | } | ||
617 | //ROOT_GROUP | ||
618 | t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n" | ||
619 | << "\t\t\t" << "children = (" << "\n" | ||
620 | << varGlue("QMAKE_PBX_GROUPS", "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
621 | << "\t\t\t" << ");" << "\n" | ||
622 | << "\t\t\t" << "isa = PBXGroup;" << "\n" | ||
623 | << "\t\t\t" << "name = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n" | ||
624 | << "\t\t\t" << "path = \"\";" << "\n" | ||
625 | << "\t\t\t" << "refType = 4;" << "\n" | ||
626 | << "\t\t" << "};" << "\n"; | ||
627 | //REFERENCE | ||
628 | t << "\t\t" << keyFor("QMAKE_PBX_REFERENCE") << " = {" << "\n"; | ||
629 | if(project->first("TEMPLATE") == "app") { | ||
630 | QString targ = project->first("QMAKE_ORIG_TARGET"); | ||
631 | if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { | ||
632 | targ += ".app"; | ||
633 | t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n"; | ||
634 | } else { | ||
635 | t << "\t\t\t" << "isa = PBXExecutableFileReference;" << "\n"; | ||
636 | } | ||
637 | QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") : | ||
638 | QDir::currentDirPath()) + Option::dir_sep + targ; | ||
639 | t << "\t\t\t" << "name = " << targ << ";" << "\n" | ||
640 | << "\t\t\t" << "path = \"" << targ << "\";" << "\n" | ||
641 | << "\t\t\t" << "refType = " << reftypeForFile(app) << ";" << "\n"; | ||
642 | } else { | ||
643 | QString lib = project->first("QMAKE_ORIG_TARGET"); | ||
644 | if(project->isActiveConfig("staticlib")) { | ||
645 | lib = project->first("TARGET"); | ||
646 | } else if(!project->isActiveConfig("frameworklib")) { | ||
647 | if(project->isActiveConfig("plugin")) | ||
648 | lib = project->first("TARGET"); | ||
649 | else | ||
650 | lib = project->first("TARGET_"); | ||
651 | } | ||
652 | int slsh = lib.findRev(Option::dir_sep); | ||
653 | if(slsh != -1) | ||
654 | lib = lib.right(lib.length() - slsh - 1); | ||
655 | t << "\t\t\t" << "isa = PBXLibraryReference;" << "\n" | ||
656 | << "\t\t\t" << "path = " << lib << ";\n" | ||
657 | << "\t\t\t" << "refType = " << reftypeForFile(lib) << ";" << "\n"; | ||
658 | } | ||
659 | t << "\t\t" << "};" << "\n"; | ||
660 | //TARGET | ||
661 | t << "\t\t" << keyFor("QMAKE_PBX_TARGET") << " = {" << "\n" | ||
662 | << "\t\t\t" << "buildPhases = (" << "\n" | ||
663 | << varGlue("QMAKE_PBX_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
664 | << "\t\t\t" << ");" << "\n" | ||
665 | << "\t\t\t" << "buildSettings = {" << "\n" | ||
666 | << "\t\t\t\t" << "FRAMEWORK_SEARCH_PATHS = \"\";" << "\n" | ||
667 | << "\t\t\t\t" << "HEADER_SEARCH_PATHS = \"" << fixEnvsList("INCLUDEPATH") << " " << fixEnvs(specdir()) << "\";" << "\n" | ||
668 | << "\t\t\t\t" << "LIBRARY_SEARCH_PATHS = \"" << var("QMAKE_PBX_LIBPATHS") << "\";" << "\n" | ||
669 | << "\t\t\t\t" << "OPTIMIZATION_CFLAGS = \"\";" << "\n" | ||
670 | << "\t\t\t\t" << "OTHER_CFLAGS = \"" << | ||
671 | fixEnvsList("QMAKE_CFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") << | ||
672 | varGlue("DEFINES"," -D"," -D","") << "\";" << "\n" | ||
673 | << "\t\t\t\t" << "LEXFLAGS = \"" << var("QMAKE_LEXFLAGS") << "\";" << "\n" | ||
674 | << "\t\t\t\t" << "YACCFLAGS = \"" << var("QMAKE_YACCFLAGS") << "\";" << "\n" | ||
675 | << "\t\t\t\t" << "OTHER_CPLUSPLUSFLAGS = \"" << | ||
676 | fixEnvsList("QMAKE_CXXFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") << | ||
677 | varGlue("DEFINES"," -D"," -D","") << "\";" << "\n" | ||
678 | << "\t\t\t\t" << "OTHER_REZFLAGS = \"\";" << "\n" | ||
679 | << "\t\t\t\t" << "SECTORDER_FLAGS = \"\";" << "\n" | ||
680 | << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n"; | ||
681 | #if 1 | ||
682 | t << "\t\t\t\t" << "BUILD_ROOT = \"" << QDir::currentDirPath() << "\";" << "\n"; | ||
683 | #endif | ||
684 | if(!project->isActiveConfig("staticlib")) | ||
685 | t << "\t\t\t\t" << "OTHER_LDFLAGS = \"" << fixEnvsList("SUBLIBS") << " " << | ||
686 | fixEnvsList("QMAKE_LFLAGS") << " " << fixEnvsList("QMAKE_LIBDIR_FLAGS") << | ||
687 | " " << fixEnvsList("QMAKE_LIBS") << "\";" << "\n"; | ||
688 | if(!project->isEmpty("DESTDIR")) | ||
689 | t << "\t\t\t\t" << "INSTALL_PATH = \"" << project->first("DESTDIR") << "\";" << "\n"; | ||
690 | if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") | ||
691 | t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VERSION") << "\";" << "\n"; | ||
692 | if(!project->isEmpty("OBJECTS_DIR")) | ||
693 | t << "\t\t\t\t" << "OBJECT_FILE_DIR = \"" << project->first("OBJECTS_DIR") << "\";" << "\n"; | ||
694 | if(project->first("TEMPLATE") == "app") { | ||
695 | if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) | ||
696 | t << "\t\t\t\t" << "WRAPPER_EXTENSION = app;" << "\n"; | ||
697 | t << "\t\t\t\t" << "PRODUCT_NAME = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"; | ||
698 | } else { | ||
699 | QString lib = project->first("QMAKE_ORIG_TARGET"); | ||
700 | if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) { | ||
701 | t << "\t\t\t\t" << "LIBRARY_STYLE = STATIC;" << "\n"; | ||
702 | lib = project->first("TARGET"); | ||
703 | } else { | ||
704 | t << "\t\t\t\t" << "LIBRARY_STYLE = DYNAMIC;" << "\n"; | ||
705 | if(!project->isActiveConfig("frameworklib")) { | ||
706 | if(project->isActiveConfig("plugin")) | ||
707 | lib = project->first("TARGET"); | ||
708 | else | ||
709 | lib = project->first("TARGET_"); | ||
710 | } | ||
711 | } | ||
712 | int slsh = lib.findRev(Option::dir_sep); | ||
713 | if(slsh != -1) | ||
714 | lib = lib.right(lib.length() - slsh - 1); | ||
715 | t << "\t\t\t\t" << "PRODUCT_NAME = " << lib << ";" << "\n"; | ||
716 | } | ||
717 | tmp = project->variables()["QMAKE_PBX_VARS"]; | ||
718 | for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) | ||
719 | t << "\t\t\t\t" << (*it) << " = \"" << getenv((*it)) << "\";" << "\n"; | ||
720 | t << "\t\t\t" << "};" << "\n" | ||
721 | << "\t\t\t" << "conditionalBuildSettings = {" << "\n" | ||
722 | << "\t\t\t" << "};" << "\n" | ||
723 | << "\t\t\t" << "dependencies = (" << "\n" | ||
724 | << varGlue("QMAKE_PBX_TARGETDEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
725 | << "\t\t\t" << ");" << "\n" | ||
726 | << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_REFERENCE") << ";" << "\n" | ||
727 | << "\t\t\t" << "shouldUseHeadermap = 1;" << "\n"; | ||
728 | if(project->first("TEMPLATE") == "app") { | ||
729 | if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { | ||
730 | t << "\t\t\t" << "isa = PBXApplicationTarget;" << "\n" | ||
731 | << "\t\t\t" << "productSettingsXML = " << "\"" << "<?xml version=" | ||
732 | << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n" | ||
733 | << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/" | ||
734 | << "Library/DTDs/PropertyList.dtd\\\">" << "\n" | ||
735 | << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n" | ||
736 | << "\t\t\t\t" << "<dict>" << "\n" | ||
737 | << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n" | ||
738 | << "\t\t\t\t\t" << "<string>English</string>" << "\n" | ||
739 | << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n" | ||
740 | << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n" | ||
741 | << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n" | ||
742 | << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n" | ||
743 | << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n" | ||
744 | << "\t\t\t\t\t" << "<string>6.0</string>" << "\n" | ||
745 | << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n" | ||
746 | << "\t\t\t\t\t" << "<string>APPL</string>" << "\n" | ||
747 | << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n" | ||
748 | << "\t\t\t\t\t" << "<string>????</string>" << "\n" | ||
749 | << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n" | ||
750 | << "\t\t\t\t\t" << "<string>0.1</string>" << "\n" | ||
751 | << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n" | ||
752 | << "\t\t\t\t\t" << "<true/>" << "\n" | ||
753 | << "\t\t\t\t" << "</dict>" << "\n" | ||
754 | << "\t\t\t\t" << "</plist>" << "\";" << "\n"; | ||
755 | } else { | ||
756 | t << "\t\t\t" << "isa = PBXToolTarget;" << "\n"; | ||
757 | } | ||
758 | t << "\t\t\t" << "name = \"" << project->first("QMAKE_ORIG_TARGET") << "\";" << "\n" | ||
759 | << "\t\t\t" << "productName = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"; | ||
760 | } else { | ||
761 | QString lib = project->first("QMAKE_ORIG_TARGET"); | ||
762 | if(!project->isActiveConfig("frameworklib")) | ||
763 | lib.prepend("lib"); | ||
764 | t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n" | ||
765 | << "\t\t\t" << "name = \"" << lib << "\";" << "\n" | ||
766 | << "\t\t\t" << "productName = " << lib << ";" << "\n"; | ||
767 | } | ||
768 | if(!project->isEmpty("DESTDIR")) | ||
769 | t << "\t\t\t" << "productInstallPath = \"" << project->first("DESTDIR") << "\";" << "\n"; | ||
770 | t << "\t\t" << "};" << "\n"; | ||
771 | //DEBUG/RELEASE | ||
772 | for(i = 0; i < 2; i++) { | ||
773 | bool as_release = !i; | ||
774 | if(project->isActiveConfig("debug")) | ||
775 | as_release = i; | ||
776 | QString key = "QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG"); | ||
777 | key = keyFor(key); | ||
778 | project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key); | ||
779 | t << "\t\t" << key << " = {" << "\n" | ||
780 | << "\t\t\t" << "buildRules = (" << "\n" | ||
781 | << "\t\t\t" << ");" << "\n" | ||
782 | << "\t\t\t" << "buildSettings = {" << "\n" | ||
783 | << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n"; | ||
784 | if(as_release) | ||
785 | t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n"; | ||
786 | t << "\t\t\t" << "};" << "\n" | ||
787 | << "\t\t\t" << "isa = PBXBuildStyle;" << "\n" | ||
788 | << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n" | ||
789 | << "\t\t" << "};" << "\n"; | ||
790 | } | ||
791 | //ROOT | ||
792 | t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n" | ||
793 | << "\t\t\t" << "buildStyles = (" << "\n" | ||
794 | << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n") | ||
795 | << "\t\t\t" << ");" << "\n" | ||
796 | << "\t\t\t" << "isa = PBXProject;" << "\n" | ||
797 | << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n" | ||
798 | << "\t\t\t" << "targets = (" << "\n" | ||
799 | << "\t\t\t\t" << keyFor("QMAKE_PBX_TARGET") << "\n" | ||
800 | << "\t\t\t" << ");" << "\n" | ||
801 | << "\t\t" << "};" << "\n"; | ||
802 | |||
803 | //FOOTER | ||
804 | t << "\t" << "};" << "\n" | ||
805 | << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n" | ||
806 | << "}" << endl; | ||
807 | |||
808 | QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), | ||
809 | QDir::currentDirPath()); | ||
810 | QFile mkwrapf(mkwrap); | ||
811 | if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { | ||
812 | debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); | ||
813 | QTextStream mkwrapt(&mkwrapf); | ||
814 | writeHeader(mkwrapt); | ||
815 | const char *cleans = "uiclean mocclean preprocess_clean "; | ||
816 | mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" | ||
817 | << "all:" << "\n\t" | ||
818 | << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild") << "\n" | ||
819 | << "install: all" << "\n\t" | ||
820 | << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild install") << "\n" | ||
821 | << "distclean clean: preprocess_clean" << "\n\t" | ||
822 | << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild clean") << "\n" | ||
823 | << (!did_preprocess ? cleans : "") << ":" << "\n"; | ||
824 | if(did_preprocess) | ||
825 | mkwrapt << cleans << ":" << "\n\t" | ||
826 | << "make -f " | ||
827 | << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl; | ||
828 | } | ||
829 | return TRUE; | ||
830 | } | ||
831 | |||
832 | QString | ||
833 | ProjectBuilderMakefileGenerator::fixEnvs(QString file) | ||
834 | { | ||
835 | QRegExp reg_var("\\$\\((.*)\\)"); | ||
836 | for(int rep = 0; (rep = reg_var.search(file, rep)) != -1; ) { | ||
837 | if(project->variables()["QMAKE_PBX_VARS"].findIndex(reg_var.cap(1)) == -1) | ||
838 | project->variables()["QMAKE_PBX_VARS"].append(reg_var.cap(1)); | ||
839 | rep += reg_var.matchedLength(); | ||
840 | } | ||
841 | return file; | ||
842 | } | ||
843 | |||
844 | QString | ||
845 | ProjectBuilderMakefileGenerator::fixEnvsList(QString where) | ||
846 | { | ||
847 | QString ret; | ||
848 | const QStringList &l = project->variables()[where]; | ||
849 | for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { | ||
850 | fixEnvs((*it)); | ||
851 | if(!ret.isEmpty()) | ||
852 | ret += " "; | ||
853 | ret += (*it); | ||
854 | } | ||
855 | return ret; | ||
856 | } | ||
857 | |||
858 | QString | ||
859 | ProjectBuilderMakefileGenerator::keyFor(QString block) | ||
860 | { | ||
861 | #if 0 //This make this code much easier to debug.. | ||
862 | return block; | ||
863 | #endif | ||
864 | |||
865 | QString ret; | ||
866 | if(!keys.contains(block)) { | ||
867 | #if 0 | ||
868 | static unsigned int r = 0; | ||
869 | ret.sprintf("%024x", ++r); | ||
870 | #else //not really necesary, but makes it look more interesting.. | ||
871 | static struct { unsigned int a1, a2, a3; } r = { 0, 0, 0 }; | ||
872 | if(!r.a1 && !r.a2 && !r.a3) { | ||
873 | r.a1 = rand(); | ||
874 | r.a2 = rand(); | ||
875 | r.a3 = rand(); | ||
876 | } | ||
877 | switch(rand() % 3) { | ||
878 | case 0: ++r.a1; break; | ||
879 | case 1: ++r.a2; break; | ||
880 | case 2: ++r.a3; break; | ||
881 | } | ||
882 | ret.sprintf("%08x%08x%08x", r.a1, r.a2, r.a3); | ||
883 | #endif | ||
884 | ret = ret.upper(); | ||
885 | keys.insert(block, ret); | ||
886 | } else { | ||
887 | ret = keys[block]; | ||
888 | } | ||
889 | return ret; | ||
890 | } | ||
891 | |||
892 | bool | ||
893 | ProjectBuilderMakefileGenerator::openOutput(QFile &file) const | ||
894 | { | ||
895 | if(project->first("TEMPLATE") != "subdirs") { | ||
896 | QFileInfo fi(file); | ||
897 | if(fi.extension() != "pbxproj" || file.name().isEmpty()) { | ||
898 | QString output = file.name(); | ||
899 | if(fi.isDir()) | ||
900 | output += QDir::separator(); | ||
901 | if(fi.extension() != "pbproj") { | ||
902 | if(file.name().isEmpty() || fi.isDir()) | ||
903 | output += project->first("TARGET"); | ||
904 | output += QString(".pbproj") + QDir::separator(); | ||
905 | } else if(output[(int)output.length() - 1] != QDir::separator()) { | ||
906 | output += QDir::separator(); | ||
907 | } | ||
908 | output += QString("project.pbxproj"); | ||
909 | file.setName(output); | ||
910 | } | ||
911 | bool ret = UnixMakefileGenerator::openOutput(file); | ||
912 | ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); | ||
913 | Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); | ||
914 | return ret; | ||
915 | } | ||
916 | return UnixMakefileGenerator::openOutput(file); | ||
917 | } | ||
918 | |||
919 | /* This function is such a hack it is almost pointless, but it | ||
920 | eliminates the warning message from ProjectBuilder that the project | ||
921 | file is for an older version. I guess this could be used someday if | ||
922 | the format of the output is dependant upon the version of | ||
923 | ProjectBuilder as well. | ||
924 | */ | ||
925 | int | ||
926 | ProjectBuilderMakefileGenerator::pbuilderVersion() const | ||
927 | { | ||
928 | QString ret; | ||
929 | if(project->isEmpty("QMAKE_PBUILDER_VERSION")) { | ||
930 | QString version, version_plist = project->first("QMAKE_PBUILDER_VERSION_PLIST"); | ||
931 | if(version_plist.isEmpty()) | ||
932 | version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; | ||
933 | else | ||
934 | version_plist = version_plist.replace(QRegExp("\""), ""); | ||
935 | QFile version_file(version_plist); | ||
936 | if(version_file.open(IO_ReadOnly)) { | ||
937 | debug_msg(1, "pbuilder: version.plist: Reading file: %s", version_plist.latin1()); | ||
938 | QTextStream plist(&version_file); | ||
939 | |||
940 | bool in_dict = FALSE; | ||
941 | QString current_key; | ||
942 | QRegExp keyreg("^<key>(.*)</key>$"), stringreg("^<string>(.*)</string>$"); | ||
943 | while(!plist.eof()) { | ||
944 | QString line = plist.readLine().stripWhiteSpace(); | ||
945 | if(line == "<dict>") | ||
946 | in_dict = TRUE; | ||
947 | else if(line == "</dict>") | ||
948 | in_dict = FALSE; | ||
949 | else if(in_dict) { | ||
950 | if(keyreg.exactMatch(line)) | ||
951 | current_key = keyreg.cap(1); | ||
952 | else if(current_key == "CFBundleShortVersionString" && stringreg.exactMatch(line)) | ||
953 | version = stringreg.cap(1); | ||
954 | } | ||
955 | } | ||
956 | version_file.close(); | ||
957 | } else debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1()); | ||
958 | if(version.startsWith("2.0")) | ||
959 | ret = "38"; | ||
960 | else if(version == "1.1") | ||
961 | ret = "34"; | ||
962 | } else { | ||
963 | ret = project->first("QMAKE_PBUILDER_VERSION"); | ||
964 | } | ||
965 | if(!ret.isEmpty()) { | ||
966 | bool ok; | ||
967 | int int_ret = ret.toInt(&ok); | ||
968 | if(ok) { | ||
969 | debug_msg(1, "pbuilder: version.plist: Got version: %d", int_ret); | ||
970 | return int_ret; | ||
971 | } | ||
972 | } | ||
973 | debug_msg(1, "pbuilder: version.plist: Fallback to default version"); | ||
974 | return 34; //my fallback | ||
975 | } | ||
976 | |||
977 | QString | ||
978 | ProjectBuilderMakefileGenerator::reftypeForFile(QString where) | ||
979 | { | ||
980 | if(QDir::isRelativePath(where)) | ||
981 | return "4"; //relative | ||
982 | return "0"; //absolute | ||
983 | } | ||
diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h new file mode 100644 index 0000000..ec2e1be --- a/dev/null +++ b/qmake/generators/mac/pbuilder_pbx.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /**************************************************************************** | ||
2 | ** $Id$ | ||
3 | ** | ||
4 | ** Definition of ________ class. | ||
5 | ** | ||
6 | ** Created : 970521 | ||
7 | ** | ||
8 | ** Copyright (C) 1992-2000 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 | #ifndef __PBUILDERMAKE_H__ | ||
38 | #define __PBUILDERMAKE_H__ | ||
39 | |||
40 | #include "unixmake.h" | ||
41 | |||
42 | class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator | ||
43 | { | ||
44 | QString pbx_dir; | ||
45 | int pbuilderVersion() const; | ||
46 | bool writeMakeParts(QTextStream &); | ||
47 | bool writeMakefile(QTextStream &); | ||
48 | |||
49 | QMap<QString, QString> keys; | ||
50 | QString keyFor(QString file); | ||
51 | QString fixEnvs(QString file); | ||
52 | QString fixEnvsList(QString where); | ||
53 | QString reftypeForFile(QString file); | ||
54 | |||
55 | public: | ||
56 | ProjectBuilderMakefileGenerator(QMakeProject *p); | ||
57 | ~ProjectBuilderMakefileGenerator(); | ||
58 | |||
59 | virtual bool openOutput(QFile &) const; | ||
60 | protected: | ||
61 | virtual bool doDepends() const { return FALSE; } //never necesary | ||
62 | }; | ||
63 | |||
64 | inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator() | ||
65 | { } | ||
66 | |||
67 | |||
68 | #endif /* __PBUILDERMAKE_H__ */ | ||