source: trunk/qmake/generators/mac/pbuilder_pbx.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: 56.6 KB
Line 
1/****************************************************************************
2** $Id: pbuilder_pbx.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of ProjectBuilderMakefileGenerator 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 "pbuilder_pbx.h"
37#include "option.h"
38#include "meta.h"
39#include <qdir.h>
40#include <qdict.h>
41#include <qregexp.h>
42#include <stdlib.h>
43#include <time.h>
44#include "qtmd5.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
52ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(QMakeProject *p) : UnixMakefileGenerator(p)
53{
54
55}
56
57bool
58ProjectBuilderMakefileGenerator::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 project->variables()["MAKEFILE"].clear();
68 project->variables()["MAKEFILE"].append("Makefile");
69 if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib")
70 return writeMakeParts(t);
71 else if(project->first("TEMPLATE") == "subdirs")
72 return writeSubdirs(t, FALSE);
73 return FALSE;
74}
75
76bool
77ProjectBuilderMakefileGenerator::writeSubdirs(QTextStream &t, bool direct)
78{
79 QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
80 QDir::currentDirPath());
81 QFile mkwrapf(mkwrap);
82 if(mkwrapf.open(IO_WriteOnly | IO_Translate)) {
83 debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1());
84 QTextStream mkwrapt(&mkwrapf);
85 UnixMakefileGenerator::writeSubdirs(mkwrapt, direct);
86 }
87
88 //HEADER
89 t << "// !$*UTF8*$!" << "\n"
90 << "{" << "\n"
91 << "\t" << "archiveVersion = 1;" << "\n"
92 << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n"
93 << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n"
94 << "\t" << "objects = {" << endl;
95
96 //SUBDIRS
97 QStringList subdirs = project->variables()["SUBDIRS"];
98 QString oldpwd = QDir::currentDirPath();
99 QMap<QString, QStringList> groups;
100 for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) {
101 QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE));
102 if(fi.exists()) {
103 if(fi.isDir()) {
104 QString profile = (*it);
105 if(!profile.endsWith(Option::dir_sep))
106 profile += Option::dir_sep;
107 profile += fi.baseName() + ".pro";
108 subdirs.append(profile);
109 } else {
110 QMakeProject tmp_proj;
111 QString dir = fi.dirPath(), fn = fi.fileName();
112 if(!dir.isEmpty()) {
113 if(!QDir::setCurrent(dir))
114 fprintf(stderr, "Cannot find directory: %s\n", dir.latin1());
115 }
116 if(tmp_proj.read(fn, oldpwd)) {
117 if(Option::debug_level) {
118 QMap<QString, QStringList> &vars = tmp_proj.variables();
119 for(QMap<QString, QStringList>::Iterator it = vars.begin();
120 it != vars.end(); ++it) {
121 if(it.key().left(1) != "." && !it.data().isEmpty())
122 debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(),
123 it.data().join(" :: ").latin1());
124 }
125 }
126 if(tmp_proj.first("TEMPLATE") == "subdirs") {
127 subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]);
128 } else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") {
129 QString pbxproj = QDir::currentDirPath() + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix();
130 if(!QFile::exists(pbxproj)) {
131 warn_msg(WarnLogic, "Ignored (not found) '%s'", pbxproj.latin1());
132 goto nextfile; // # Dirty!
133 }
134 project->variables()["QMAKE_PBX_SUBDIRS"] += pbxproj;
135 //PROJECTREF
136 {
137 bool in_root = TRUE;
138 QString name = QDir::currentDirPath();
139 QString project_key = keyFor(pbxproj + "_PROJECTREF");
140 if(project->isActiveConfig("flat")) {
141 QString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE);
142 if(flat_file.find(Option::dir_sep) != -1) {
143 QStringList dirs = QStringList::split(Option::dir_sep, flat_file);
144 name = dirs.back();
145 }
146 } else {
147 QString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE);
148 if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) {
149 QString last_grp("QMAKE_PBX_HEIR_GROUP");
150 QStringList dirs = QStringList::split(Option::dir_sep, flat_file);
151 name = dirs.back();
152 for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) {
153 QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp));
154 if(dir_it == dirs.begin()) {
155 if(!groups.contains(new_grp))
156 project->variables()["QMAKE_PBX_GROUPS"].append(new_grp_key);
157 } else {
158 if(!groups[last_grp].contains(new_grp_key))
159 groups[last_grp] += new_grp_key;
160 }
161 last_grp = new_grp;
162 }
163 groups[last_grp] += project_key;
164 in_root = FALSE;
165 }
166 }
167 if(in_root)
168 project->variables()["QMAKE_PBX_GROUPS"] += project_key;
169 t << "\t\t" << project_key << " = {" << "\n"
170 << "\t\t\t" << "isa = PBXFileReference;" << "\n"
171 << "\t\t\t" << "name = " << tmp_proj.first("TARGET") << ";" << "\n"
172 << "\t\t\t" << "path = " << pbxproj << ";" << "\n"
173 << "\t\t\t" << "refType = 0;" << "\n"
174 << "\t\t\t" << "sourceTree = \"<absolute>\";" << "\n"
175 << "\t\t" << "};" << "\n";
176 //PRODUCTGROUP
177 t << "\t\t" << keyFor(pbxproj + "_PRODUCTGROUP") << " = {" << "\n"
178 << "\t\t\t" << "children = (" << "\n"
179 << "\t\t\t" << ");" << "\n"
180 << "\t\t\t" << "isa = PBXGroup;" << "\n"
181 << "\t\t\t" << "name = Products;" << "\n"
182 << "\t\t\t" << "refType = 4;" << "\n"
183 << "\t\t\t" << "sourceTree = \"<group>\";" << "\n"
184 << "\t\t" << "};" << "\n";
185 }
186 }
187 }
188nextfile:
189 QDir::setCurrent(oldpwd);
190 }
191 }
192 }
193 for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) {
194 t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n"
195 << "\t\t\t" << "isa = PBXGroup;" << "\n"
196 << "\t\t\t" << "children = (" << "\n"
197 << valGlue(grp_it.data(), "\t\t\t\t", ",\n\t\t\t\t", "\n")
198 << "\t\t\t" << ");" << "\n"
199 << "\t\t\t" << "name = \"" << grp_it.key().section(Option::dir_sep, -1) << "\";" << "\n"
200 << "\t\t\t" << "refType = 4;" << "\n"
201 << "\t\t" << "};" << "\n";
202 }
203
204 //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER
205 //BUILDSTYLE
206 QString active_buildstyle;
207#if 0
208 for(int as_release = 0; as_release < 2; as_release++)
209#else
210 bool as_release = !project->isActiveConfig("debug");
211#endif
212 {
213 QString key = keyFor("QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG"));
214 if(project->isActiveConfig("debug") != as_release)
215 active_buildstyle = key;
216 project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key);
217 t << "\t\t" << key << " = {" << "\n"
218 << "\t\t\t" << "buildRules = (" << "\n"
219 << "\t\t\t" << ");" << "\n"
220 << "\t\t\t" << "buildSettings = {" << "\n"
221 << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n";
222 if(as_release)
223 t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n";
224 t << "\t\t\t" << "};" << "\n"
225 << "\t\t\t" << "isa = PBXBuildStyle;" << "\n"
226 << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n"
227 << "\t\t" << "};" << "\n";
228 }
229
230 //ROOT_GROUP
231 t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n"
232 << "\t\t\t" << "children = (" << "\n"
233 << varGlue("QMAKE_PBX_GROUPS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
234 << "\t\t\t" << ");" << "\n"
235 << "\t\t\t" << "isa = PBXGroup;" << "\n"
236 << "\t\t\t" << "refType = 4;" << "\n"
237 << "\t\t\t" << "sourceTree = \"<group>\";" << "\n"
238 << "\t\t" << "};" << "\n";
239
240 //ROOT
241 t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n"
242 << "\t\t\t" << "buildSettings = {" << "\n"
243 << "\t\t\t" << "};" << "\n"
244 << "\t\t\t" << "buildStyles = (" << "\n"
245 << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
246 << "\t\t\t" << ");" << "\n"
247 << "\t\t\t" << "isa = PBXProject;" << "\n"
248 << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n"
249 << "\t\t\t" << "projectDirPath = \"\";" << "\n"
250 << "\t\t\t" << "projectReferences = (" << "\n";
251 {
252 QStringList &libdirs = project->variables()["QMAKE_PBX_SUBDIRS"];
253 for(QStringList::Iterator it = libdirs.begin(); it != libdirs.end(); ++it)
254 t << "\t\t\t\t" << "{" << "\n"
255 << "\t\t\t\t\t" << "ProductGroup = " << keyFor((*it) + "_PRODUCTGROUP") << ";" << "\n"
256 << "\t\t\t\t\t" << "ProjectRef = " << keyFor((*it) + "_PROJECTREF") << ";" << "\n"
257 << "\t\t\t\t" << "}," << "\n";
258 }
259 t << "\t\t\t" << ");" << "\n"
260 << "\t\t\t" << "targets = (" << "\n"
261 << "\t\t\t" << ");" << "\n"
262 << "\t\t" << "};" << "\n";
263
264 //FOOTER
265 t << "\t" << "};" << "\n"
266 << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n"
267 << "}" << endl;
268
269 return TRUE;
270}
271
272bool
273ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
274{
275 int i;
276 QStringList tmp;
277 bool did_preprocess = FALSE;
278
279 //HEADER
280 t << "// !$*UTF8*$!" << "\n"
281 << "{" << "\n"
282 << "\t" << "archiveVersion = 1;" << "\n"
283 << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n"
284 << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n"
285 << "\t" << "objects = {" << endl;
286
287 //MAKE QMAKE equivlant
288 if(!project->isActiveConfig("no_autoqmake") && project->projectFile() != "(stdin)") {
289 QString mkfile = pbx_dir + Option::dir_sep + "qt_makeqmake.mak";
290 QFile mkf(mkfile);
291 if(mkf.open(IO_WriteOnly | IO_Translate)) {
292 debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
293 QTextStream mkt(&mkf);
294 writeHeader(mkt);
295 mkt << "QMAKE = " <<
296 (project->isEmpty("QMAKE_QMAKE") ? QString("$(QTDIR)/bin/qmake") :
297 var("QMAKE_QMAKE")) << endl;
298 writeMakeQmake(mkt);
299 mkf.close();
300 }
301 QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE");
302 mkfile = fileFixify(mkfile, QDir::currentDirPath());
303 project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key);
304 t << "\t\t" << phase_key << " = {" << "\n"
305 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
306 << "\t\t\t" << "files = (" << "\n"
307 << "\t\t\t" << ");" << "\n"
308 << "\t\t\t" << "generatedFileNames = (" << "\n"
309 << "\t\t\t" << ");" << "\n"
310 << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
311 << "\t\t\t" << "name = \"Qt Qmake\";" << "\n"
312 << "\t\t\t" << "neededFileNames = (" << "\n"
313 << "\t\t\t" << ");" << "\n"
314 << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
315 << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() <<
316 " -f " << mkfile << "\";" << "\n"
317 << "\t\t" << "};" << "\n";
318 }
319
320 //DUMP SOURCES
321 QMap<QString, QStringList> groups;
322 QString srcs[] = { "HEADERS", "SOURCES", "SRCMOC", "UICIMPLS", "QMAKE_IMAGE_COLLECTION",
323 "FORMS", "QMAKE_INTERNAL_INCLUDED_FILES", QString::null };
324 for(i = 0; !srcs[i].isNull(); i++) {
325 tmp = project->variables()[srcs[i]];
326 if(srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") {
327 QString pfile = project->projectFile();
328 if(pfile != "(stdin)")
329 tmp.prepend(pfile);
330 }
331 QStringList &src_list = project->variables()["QMAKE_PBX_" + srcs[i]];
332 QStringList &root_group_list = project->variables()["QMAKE_PBX_GROUPS"];
333
334 //hard coded groups..
335 QString src_group;
336 if(srcs[i] == "SOURCES")
337 src_group = "Sources";
338 else if(srcs[i] == "HEADERS")
339 src_group = "Headers";
340 else if(srcs[i] == "SRCMOC")
341 src_group = "Sources [moc]";
342 else if(srcs[i] == "UICIMPLS" || srcs[i] == "FORMS")
343 src_group = "Sources [uic]";
344 else if(srcs[i] == "QMAKE_IMAGE_COLLECTION")
345 src_group = "Sources [images]";
346 else if(srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES")
347 src_group = "Sources [qmake]";
348
349 for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) {
350 QStringList files = (*it);
351 bool buildable = TRUE;
352 if(srcs[i] == "FORMS") {
353 QString form_dot_h = (*it) + Option::h_ext.first();
354 if(QFile::exists(form_dot_h))
355 files += form_dot_h;
356 buildable = FALSE;
357 } else if(srcs[i] == "HEADERS" || srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") {
358 buildable = FALSE;
359 }
360
361 files = fileFixify(files);
362 for(QStringList::Iterator file_it = files.begin(); file_it != files.end(); ++file_it) {
363 QString file = (*file_it);
364 if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0])
365 file = file.mid(1, file.length()-2);
366 if(file.endsWith(Option::cpp_moc_ext) || file.endsWith(Option::prl_ext))
367 continue;
368 bool in_root = TRUE;
369 QString src_key = keyFor(file), name = file;
370 if(project->isActiveConfig("flat")) {
371 QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE);
372 if(flat_file.find(Option::dir_sep) != -1) {
373 QStringList dirs = QStringList::split(Option::dir_sep, flat_file);
374 name = dirs.back();
375 }
376 } else {
377 QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE);
378 if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) {
379 QString last_grp("QMAKE_PBX_" + src_group + "_HEIR_GROUP");
380 QStringList dirs = QStringList::split(Option::dir_sep, flat_file);
381 name = dirs.back();
382 dirs.pop_back(); //remove the file portion as it will be added via src_key
383 for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) {
384 QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp));
385 if(dir_it == dirs.begin()) {
386 if(!src_list.contains(new_grp_key))
387 src_list.append(new_grp_key);
388 } else {
389 if(!groups[last_grp].contains(new_grp_key))
390 groups[last_grp] += new_grp_key;
391 }
392 last_grp = new_grp;
393 }
394 groups[last_grp] += src_key;
395 in_root = FALSE;
396 }
397 }
398 if(in_root)
399 src_list.append(src_key);
400 //source reference
401 t << "\t\t" << src_key << " = {" << "\n"
402 << "\t\t\t" << "isa = PBXFileReference;" << "\n"
403 << "\t\t\t" << "name = \"" << name << "\";" << "\n"
404 << "\t\t\t" << "path = \"" << file << "\";" << "\n"
405 << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n";
406 if (ideType() == MAC_XCODE) {
407 QString filetype;
408 for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) {
409 if(file.endsWith((*cppit))) {
410 filetype = "sourcecode.cpp.cpp";
411 break;
412 }
413 }
414 if(!filetype.isNull())
415 t << "\t\t\t" << "lastKnownFileType = " << filetype << ";" << "\n";
416 }
417 t << "\t\t" << "};" << "\n";
418 if(buildable) { //build reference
419 QString obj_key = file + ".o";
420 obj_key = keyFor(obj_key);
421 t << "\t\t" << obj_key << " = {" << "\n"
422 << "\t\t\t" << "fileRef = " << src_key << ";" << "\n"
423 << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
424 << "\t\t\t" << "settings = {" << "\n"
425 << "\t\t\t\t" << "ATTRIBUTES = (" << "\n"
426 << "\t\t\t\t" << ");" << "\n"
427 << "\t\t\t" << "};" << "\n"
428 << "\t\t" << "};" << "\n";
429 project->variables()["QMAKE_PBX_OBJ"].append(obj_key);
430 }
431 }
432 }
433 if(!src_list.isEmpty()) {
434 if(srcs[i] == "SOURCES") {
435 if(project->first("TEMPLATE") == "app" && !project->isEmpty("RC_FILE")) { //Icon
436 QString icns_file = keyFor("ICNS_FILE");
437 src_list.append(icns_file);
438 t << "\t\t" << icns_file << " = {" << "\n"
439 << "\t\t\t" << "isa = PBXFileReference;" << "\n"
440 << "\t\t\t" << "path = \"" << project->first("RC_FILE") << "\";" << "\n"
441 << "\t\t\t" << "refType = " << reftypeForFile(project->first("RC_FILE")) << ";" << "\n"
442 << "\t\t" << "};" << "\n";
443 t << "\t\t" << keyFor("ICNS_FILE_REFERENCE") << " = {" << "\n"
444 << "\t\t\t" << "fileRef = " << icns_file << ";" << "\n"
445 << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
446 << "\t\t\t" << "settings = {" << "\n"
447 << "\t\t\t" << "};" << "\n"
448 << "\t\t" << "};" << "\n";
449 }
450 }
451
452 QString src_group_key = keyFor(src_group);
453 if(root_group_list.findIndex(src_group_key) == -1)
454 root_group_list += src_group_key;
455 groups[src_group] += src_list;
456 }
457 }
458 for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) {
459 t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n"
460 << "\t\t\t" << "isa = PBXGroup;" << "\n"
461 << "\t\t\t" << "children = (" << "\n"
462 << valGlue(grp_it.data(), "\t\t\t\t", ",\n\t\t\t\t", "\n")
463 << "\t\t\t" << ");" << "\n"
464 << "\t\t\t" << "name = \"" << grp_it.key().section(Option::dir_sep, -1) << "\";" << "\n"
465 << "\t\t\t" << "refType = 4;" << "\n"
466 << "\t\t" << "};" << "\n";
467 }
468
469 //PREPROCESS BUILDPHASE (just a makefile)
470 if(!project->isEmpty("UICIMPLS") || !project->isEmpty("SRCMOC") ||
471 !project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) {
472 QString mkfile = pbx_dir + Option::dir_sep + "qt_preprocess.mak";
473 QFile mkf(mkfile);
474 if(mkf.open(IO_WriteOnly | IO_Translate)) {
475 did_preprocess = TRUE;
476 debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
477 QTextStream mkt(&mkf);
478 writeHeader(mkt);
479 mkt << "MOC = " << Option::fixPathToTargetOS(var("QMAKE_MOC")) << endl;
480 mkt << "UIC = " << Option::fixPathToTargetOS(var("QMAKE_UIC")) << endl;
481 mkt << "LEX = " << var("QMAKE_LEX") << endl;
482 mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
483 mkt << "YACC = " << var("QMAKE_YACC") << endl;
484 mkt << "YACCFLAGS = " << var("QMAKE_YACCFLAGS") << endl;
485 mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
486 mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl;
487 mkt << "FORMS = " << varList("UICIMPLS") << endl;
488 mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl;
489 mkt << "MOCS = " << varList("SRCMOC") << endl;
490 mkt << "PARSERS =";
491 if(!project->isEmpty("YACCSOURCES")) {
492 QStringList &yaccs = project->variables()["YACCSOURCES"];
493 for(QStringList::Iterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) {
494 QFileInfo fi((*yit));
495 mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE)
496 << Option::yacc_mod << Option::cpp_ext.first();
497 }
498 }
499 if(!project->isEmpty("LEXSOURCES")) {
500 QStringList &lexs = project->variables()["LEXSOURCES"];
501 for(QStringList::Iterator lit = lexs.begin(); lit != lexs.end(); ++lit) {
502 QFileInfo fi((*lit));
503 mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE)
504 << Option::lex_mod << Option::cpp_ext.first();
505 }
506 }
507 mkt << "\n";
508 mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS) $(IMAGES)" << endl;
509 mkt << "clean preprocess_clean: mocclean uiclean parser_clean" << endl << endl;
510 mkt << "mocclean:" << "\n";
511 if(!project->isEmpty("SRCMOC"))
512 mkt << "\t-rm -f $(MOCS)" << "\n";
513 mkt << "uiclean:" << "\n";
514 if(!project->isEmpty("UICIMPLS"))
515 mkt << "\t-rm -f $(FORMS)" << "\n";
516 if(!project->isEmpty("QMAKE_IMAGE_COLLECTION"))
517 mkt << "\t-rm -f $(IMAGES)" << "\n";
518 mkt << "parser_clean:" << "\n";
519 if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES"))
520 mkt << "\t-rm -f $(PARSERS)" << "\n";
521 writeUicSrc(mkt, "FORMS");
522 writeMocSrc(mkt, "HEADERS");
523 writeMocSrc(mkt, "SOURCES");
524 writeMocSrc(mkt, "UICDECLS");
525 writeYaccSrc(mkt, "YACCSOURCES");
526 writeLexSrc(mkt, "LEXSOURCES");
527 writeImageSrc(mkt, "QMAKE_IMAGE_COLLECTION");
528 mkf.close();
529 }
530 mkfile = fileFixify(mkfile, QDir::currentDirPath());
531 QString phase_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET");
532// project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
533 project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key);
534 t << "\t\t" << phase_key << " = {" << "\n"
535 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
536 << "\t\t\t" << "files = (" << "\n"
537 << "\t\t\t" << ");" << "\n"
538 << "\t\t\t" << "generatedFileNames = (" << "\n"
539 << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n")
540 << "\t\t\t" << ");" << "\n"
541 << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
542 << "\t\t\t" << "name = \"Qt Preprocessors\";" << "\n"
543 << "\t\t\t" << "neededFileNames = (" << "\n"
544 << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n")
545 << "\t\t\t" << ");" << "\n"
546 << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
547 << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() <<
548 " -f " << mkfile << "\";" << "\n"
549 << "\t\t" << "};" << "\n";
550 }
551
552 //SOURCE BUILDPHASE
553 if(!project->isEmpty("QMAKE_PBX_OBJ")) {
554 QString grp = "Build Sources", key = keyFor(grp);
555 project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
556 t << "\t\t" << key << " = {" << "\n"
557 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
558 << "\t\t\t" << "files = (" << "\n"
559 << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n")
560 << "\t\t\t" << ");" << "\n"
561 << "\t\t\t" << "isa = PBXSourcesBuildPhase;" << "\n"
562 << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
563 << "\t\t" << "};" << "\n";
564 }
565
566 if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
567 QStringList &libdirs = project->variables()["QMAKE_PBX_LIBPATHS"];
568 QString libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
569 for(i = 0; !libs[i].isNull(); i++) {
570 tmp = project->variables()[libs[i]];
571 for(QStringList::Iterator it = tmp.begin(); it != tmp.end();) {
572 bool remove = FALSE;
573 QString library, name, opt = (*it).stripWhiteSpace();
574 if(opt.length() >= 2 && (opt[0] == '"' || opt[0] == '\'') && opt[(int) opt.length()-1] == opt[0])
575 opt = opt.mid(1, opt.length()-2);
576 if(opt.startsWith("-L")) {
577 QString r = opt.right(opt.length() - 2);
578 fixEnvVariables(r);
579 libdirs.append(r);
580 } else if(opt == "-prebind") {
581 project->variables()["QMAKE_DO_PREBINDING"].append("TRUE");
582 remove = TRUE;
583 } else if(opt.startsWith("-l")) {
584 name = opt.right(opt.length() - 2);
585 QString lib("lib" + name);
586 for(QStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) {
587 if(project->isActiveConfig("link_prl")) {
588 /* This isn't real nice, but it is real usefull. This looks in a prl
589 for what the library will ultimately be called so we can stick it
590 in the ProjectFile. If the prl format ever changes (not likely) then
591 this will not really work. However, more concerning is that it will
592 encode the version number in the Project file which might be a bad
593 things in days to come? --Sam
594 */
595 QString lib_file = (*lit) + Option::dir_sep + lib;
596 if(QMakeMetaInfo::libExists(lib_file)) {
597 QMakeMetaInfo libinfo;
598 if(libinfo.readLib(lib_file)) {
599 if(!libinfo.isEmpty("QMAKE_PRL_TARGET")) {
600 library = (*lit) + Option::dir_sep + libinfo.first("QMAKE_PRL_TARGET");
601 debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)",
602 opt.latin1(), lib_file.latin1(), library.latin1());
603 remove = TRUE;
604 }
605 }
606 }
607 }
608 if(!remove) {
609 QString extns[] = { ".dylib", ".so", ".a", QString::null };
610 for(int n = 0; !remove && !extns[n].isNull(); n++) {
611 QString tmp = (*lit) + Option::dir_sep + lib + extns[n];
612 if(QFile::exists(tmp)) {
613 library = tmp;
614 debug_msg(1, "pbuilder: Found library (%s) via %s",
615 opt.latin1(), library.latin1());
616 remove = TRUE;
617 }
618 }
619 }
620 }
621 } else if(opt == "-framework") {
622 ++it;
623 if(it == tmp.end())
624 break;
625 QStringList &fdirs = project->variables()["QMAKE_FRAMEWORKDIR"];
626 if(fdirs.isEmpty())
627 fdirs.append("/System/Library/Frameworks/");
628 for(QStringList::Iterator fit = fdirs.begin(); fit != fdirs.end(); ++fit) {
629 if(QFile::exists((*fit) + QDir::separator() + (*it) + ".framework")) {
630 --it;
631 it = tmp.remove(it);
632 remove = TRUE;
633 library = (*fit) + Option::dir_sep + (*it) + ".framework";
634 break;
635 }
636 }
637 } else if(opt == "-undefined") {
638 ++it; //the next option is not a library..
639 } else if(opt.left(1) != "-") {
640 remove = TRUE;
641 library = opt;
642 }
643 if(!library.isEmpty()) {
644 if(name.isEmpty()) {
645 int slsh = library.findRev(Option::dir_sep);
646 if(slsh != -1)
647 name = library.right(library.length() - slsh - 1);
648 }
649 library = fileFixify(library);
650 QString key = keyFor(library);
651 bool is_frmwrk = (library.endsWith(".framework"));
652 t << "\t\t" << key << " = {" << "\n"
653 << "\t\t\t" << "isa = " << (is_frmwrk ? "PBXFrameworkReference" : "PBXFileReference") << ";" << "\n"
654 << "\t\t\t" << "name = \"" << name << "\";" << "\n"
655 << "\t\t\t" << "path = \"" << library << "\";" << "\n"
656 << "\t\t\t" << "refType = " << reftypeForFile(library) << ";" << "\n"
657 << "\t\t" << "};" << "\n";
658 project->variables()["QMAKE_PBX_LIBRARIES"].append(key);
659 QString obj_key = library + ".o";
660 obj_key = keyFor(obj_key);
661 t << "\t\t" << obj_key << " = {" << "\n"
662 << "\t\t\t" << "fileRef = " << key << ";" << "\n"
663 << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
664 << "\t\t\t" << "settings = {" << "\n"
665 << "\t\t\t" << "};" << "\n"
666 << "\t\t" << "};" << "\n";
667 project->variables()["QMAKE_PBX_BUILD_LIBRARIES"].append(obj_key);
668 }
669 if(remove)
670 it = tmp.remove(it);
671 else
672 ++it;
673 }
674 project->variables()[libs[i]] = tmp;
675 }
676 }
677 //SUBLIBS BUILDPHASE (just another makefile)
678 if(!project->isEmpty("SUBLIBS")) {
679 QString mkfile = pbx_dir + Option::dir_sep + "qt_sublibs.mak";
680 QFile mkf(mkfile);
681 if(mkf.open(IO_WriteOnly | IO_Translate)) {
682 debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
683 QTextStream mkt(&mkf);
684 writeHeader(mkt);
685 mkt << "SUBLIBS= ";
686 tmp = project->variables()["SUBLIBS"];
687 QStringList::Iterator it;
688 for(it = tmp.begin(); it != tmp.end(); ++it)
689 t << "tmp/lib" << (*it) << ".a ";
690 t << endl << endl;
691 mkt << "sublibs: $(SUBLIBS)" << endl << endl;
692 tmp = project->variables()["SUBLIBS"];
693 for(it = tmp.begin(); it != tmp.end(); ++it)
694 t << "tmp/lib" << (*it) << ".a" << ":\n\t"
695 << var(QString("MAKELIB") + (*it)) << endl << endl;
696 mkf.close();
697 }
698 QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE");
699 mkfile = fileFixify(mkfile, QDir::currentDirPath());
700 project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key);
701 t << "\t\t" << phase_key << " = {" << "\n"
702 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
703 << "\t\t\t" << "files = (" << "\n"
704 << "\t\t\t" << ");" << "\n"
705 << "\t\t\t" << "generatedFileNames = (" << "\n"
706 << "\t\t\t" << ");" << "\n"
707 << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
708 << "\t\t\t" << "name = \"Qt Sublibs\";" << "\n"
709 << "\t\t\t" << "neededFileNames = (" << "\n"
710 << "\t\t\t" << ");" << "\n"
711 << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
712 << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() <<
713 " -f " << mkfile << "\";" << "\n"
714 << "\t\t" << "};" << "\n";
715 }
716 //LIBRARY BUILDPHASE
717 if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) {
718 tmp = project->variables()["QMAKE_PBX_LIBRARIES"];
719 if(!tmp.isEmpty()) {
720 QString grp("External Frameworks and Libraries"), key = keyFor(grp);
721 project->variables()["QMAKE_PBX_GROUPS"].append(key);
722 t << "\t\t" << key << " = {" << "\n"
723 << "\t\t\t" << "children = (" << "\n"
724 << varGlue("QMAKE_PBX_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
725 << "\t\t\t" << ");" << "\n"
726 << "\t\t\t" << "isa = PBXGroup;" << "\n"
727 << "\t\t\t" << "name = \"" << grp << "\"" << ";" << "\n"
728 << "\t\t\t" << "path = \"\";" << "\n"
729 << "\t\t\t" << "refType = 4;" << "\n"
730 << "\t\t" << "};" << "\n";
731 }
732 }
733 {
734 QString grp("Frameworks & Libraries"), key = keyFor(grp);
735 project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
736 t << "\t\t" << key << " = {" << "\n"
737 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
738 << "\t\t\t" << "files = (" << "\n"
739 << varGlue("QMAKE_PBX_BUILD_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
740 << "\t\t\t" << ");" << "\n"
741 << "\t\t\t" << "isa = PBXFrameworksBuildPhase;" << "\n"
742 << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
743 << "\t\t" << "};" << "\n";
744 }
745 if(!project->isActiveConfig("console") && project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES
746 QString grp("Bundle Resources"), key = keyFor(grp);
747 project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
748 t << "\t\t" << key << " = {" << "\n"
749 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
750 << "\t\t\t" << "files = (" << "\n"
751 << (!project->isEmpty("RC_FILE") ? keyFor("ICNS_FILE_REFERENCE") : QString(""))
752 << "\t\t\t" << ");" << "\n"
753 << "\t\t\t" << "isa = PBXResourcesBuildPhase;" << "\n"
754 << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
755 << "\t\t" << "};" << "\n";
756 }
757 { //INSTALL BUILDPHASE (sh script)
758 QString targ = project->first("TARGET");
759 if(project->first("TEMPLATE") == "app" ||
760 (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") &&
761 project->isActiveConfig("frameworklib")))
762 targ = project->first("QMAKE_ORIG_TARGET");
763 int slsh = targ.findRev(Option::dir_sep);
764 if(slsh != -1)
765 targ = targ.right(targ.length() - slsh - 1);
766 fixEnvVariables(targ);
767 QStringList links;
768 if(project->first("TEMPLATE") == "app") {
769 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console"))
770 targ += ".app";
771 } else if(!project->isActiveConfig("staticlib") &&
772 !project->isActiveConfig("frameworklib")) {
773 QString li[] = { "TARGET_", "TARGET_x", "TARGET_x.y", QString::null };
774 for(int n = 0; !li[n].isNull(); n++) {
775 QString t = project->first(li[n]);
776 slsh = t.findRev(Option::dir_sep);
777 if(slsh != -1)
778 t = t.right(t.length() - slsh);
779 fixEnvVariables(t);
780 links << t;
781 }
782 }
783 QString script = pbx_dir + Option::dir_sep + "qt_install.sh";
784 QFile shf(script);
785 if(shf.open(IO_WriteOnly | IO_Translate)) {
786 debug_msg(1, "pbuilder: Creating file: %s", script.latin1());
787 QString targ = project->first("QMAKE_ORIG_TARGET"), cpflags;
788 if(project->first("TEMPLATE") == "app") {
789 targ = project->first("TARGET");
790 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
791 targ += ".app";
792 cpflags += "-r ";
793 }
794 } else if(!project->isActiveConfig("frameworklib")) {
795 if(project->isActiveConfig("staticlib"))
796 targ = project->first("TARGET");
797 else
798 targ = project->first("TARGET_");
799 int slsh = targ.findRev(Option::dir_sep);
800 if(slsh != -1)
801 targ = targ.right(targ.length() - slsh - 1);
802 }
803 QTextStream sht(&shf);
804 QString dstdir = project->first("DESTDIR");
805 fixEnvVariables(dstdir);
806
807 sht << "#!/bin/sh" << endl;
808 //copy the actual target
809 sht << "OUT_TARG=\"" << targ << "\"\n"
810 << "[ -z \"$BUILD_ROOT\" ] || OUT_TARG=\"${BUILD_ROOT}/${OUT_TARG}\"" << endl;
811 sht << "[ \"$OUT_TARG\" = \""
812 << (dstdir.isEmpty() ? QDir::currentDirPath() + QDir::separator(): dstdir) << targ << "\" ] || "
813 << "[ \"$OUT_TARG\" = \"" << targ << "\" ] || "
814 << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << endl;
815 //rename as a framework
816 if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib"))
817 sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << targ << "\"" << endl;
818 //create all the version symlinks (just to be like unixmake)
819 for(QStringList::Iterator it = links.begin(); it != links.end(); ++it) {
820 if(targ != (*it))
821 sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << (*it) << "\"" << endl;
822 }
823 shf.close();
824#ifdef Q_OS_UNIX
825 chmod(script.latin1(), S_IRWXU | S_IRWXG);
826#endif
827 QString phase_key = keyFor("QMAKE_PBX_INSTALL_BUILDPHASE");
828 script = fileFixify(script, QDir::currentDirPath());
829 project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
830 t << "\t\t" << phase_key << " = {" << "\n"
831 << "\t\t\t" << "buildActionMask = 8;" << "\n" //only on install!
832 << "\t\t\t" << "files = (" << "\n"
833 << "\t\t\t" << ");" << "\n"
834 << "\t\t\t" << "generatedFileNames = (" << "\n"
835 << "\t\t\t" << ");" << "\n"
836 << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
837 << "\t\t\t" << "name = \"Qt Install\";" << "\n"
838 << "\t\t\t" << "neededFileNames = (" << "\n"
839 << "\t\t\t" << ");" << "\n"
840 << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
841 << "\t\t\t" << "shellScript = \"" << script << "\";" << "\n"
842 << "\t\t" << "};" << "\n";
843 }
844 }
845 if(/*ideType() == MAC_XCODE &&*/ !project->isEmpty("QMAKE_PBX_PRESCRIPT_BUILDPHASES")) {
846 // build reference
847 t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPT_BUILDREFERENCE") << " = {" << "\n"
848 << "\t\t\t" << "includeInIndex = 0;" << "\n"
849 << "\t\t\t" << "isa = PBXFileReference;" << "\n"
850 << "\t\t\t" << "path = preprocessor.out;" << "\n"
851 << "\t\t\t" << "refType = 3;" << "\n"
852 << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR;" << "\n"
853 << "\t\t" << "};" << "\n";
854 project->variables()["QMAKE_PBX_PRODUCTS"].append(keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE"));
855 //build phase
856 t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE") << " = {" << "\n"
857 << "\t\t\t" << "buildPhases = (" << "\n"
858 << varGlue("QMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
859 << "\t\t\t" << ");" << "\n"
860 << "\t\t\t" << "buildRules = (" << "\n"
861 << "\t\t\t" << ");" << "\n"
862 << "\t\t\t" << "buildSettings = {" << "\n"
863 << "\t\t\t" << "};" << "\n"
864 << "\t\t\t" << "dependencies = (" << "\n"
865 << "\t\t\t" << ");" << "\n"
866 << "\t\t\t" << "isa = PBXNativeTarget;" << "\n"
867 << "\t\t\t" << "name = \"Qt Preprocessor Steps\";" << "\n"
868 << "\t\t\t" << "productName = \"Qt Preprocessor Steps\";" << "\n"
869 << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE") << ";" << "\n"
870 << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n"
871 << "\t\t" << "};" << "\n";
872 //dependency
873 t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY") << " = {" << "\n"
874 << "\t\t\t" << "isa = PBXTargetDependency;" << "\n"
875 << "\t\t\t" << "target = " << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE") << ";" << "\n"
876 << "\t\t" << "};" << "\n";
877 project->variables()["QMAKE_PBX_TARGET_DEPENDS"].append(keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY"));
878 project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].clear(); //these are already consumed above
879 }
880
881 //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER
882 //ROOT_GROUP
883 t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n"
884 << "\t\t\t" << "children = (" << "\n"
885 << varGlue("QMAKE_PBX_GROUPS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
886 << "\t\t\t" << ");" << "\n"
887 << "\t\t\t" << "isa = PBXGroup;" << "\n"
888 << "\t\t\t" << "name = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"
889 << "\t\t\t" << "path = \"\";" << "\n"
890 << "\t\t\t" << "refType = 4;" << "\n"
891 << "\t\t" << "};" << "\n";
892 //REFERENCE
893 project->variables()["QMAKE_PBX_PRODUCTS"].append(keyFor(pbx_dir + "QMAKE_PBX_REFERENCE"));
894 t << "\t\t" << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << " = {" << "\n"
895 << "\t\t\t" << "fallbackIsa = PBXFileReference;" << "\n";
896 if(project->first("TEMPLATE") == "app") {
897 QString targ = project->first("QMAKE_ORIG_TARGET");
898 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
899 targ += ".app";
900 t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n";
901 } else {
902 t << "\t\t\t" << "isa = PBXExecutableFileReference;" << "\n";
903 }
904 QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") :
905 QDir::currentDirPath()) + Option::dir_sep + targ;
906 t << "\t\t\t" << "name = " << targ << ";" << "\n"
907 << "\t\t\t" << "path = \"" << targ << "\";" << "\n"
908 << "\t\t\t" << "refType = " << reftypeForFile(app) << ";" << "\n";
909 } else {
910 QString lib = project->first("QMAKE_ORIG_TARGET");
911 if(project->isActiveConfig("staticlib")) {
912 lib = project->first("TARGET");
913 } else if(!project->isActiveConfig("frameworklib")) {
914 if(project->isActiveConfig("plugin"))
915 lib = project->first("TARGET");
916 else
917 lib = project->first("TARGET_");
918 }
919 int slsh = lib.findRev(Option::dir_sep);
920 if(slsh != -1)
921 lib = lib.right(lib.length() - slsh - 1);
922 t << "\t\t\t" << "isa = PBXLibraryReference;" << "\n"
923 << "\t\t\t" << "expectedFileType = \"compiled.mach-o.dylib\";" << "\n"
924 << "\t\t\t" << "path = " << lib << ";\n"
925 << "\t\t\t" << "refType = " << 3/*reftypeForFile(lib)*/ << ";" << "\n"
926 << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR" << ";" << "\n";
927 }
928 t << "\t\t" << "};" << "\n";
929 { //Products group
930 QString grp("Products"), key = keyFor(grp);
931 project->variables()["QMAKE_PBX_GROUPS"].append(key);
932 t << "\t\t" << key << " = {" << "\n"
933 << "\t\t\t" << "children = (" << "\n"
934 << varGlue("QMAKE_PBX_PRODUCTS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
935 << "\t\t\t" << ");" << "\n"
936 << "\t\t\t" << "isa = PBXGroup;" << "\n"
937 << "\t\t\t" << "name = Products;" << "\n"
938 << "\t\t\t" << "refType = 4;" << "\n"
939 << "\t\t" << "};" << "\n";
940 }
941 //TARGET
942 t << "\t\t" << keyFor("QMAKE_PBX_TARGET") << " = {" << "\n"
943 << "\t\t\t" << "buildPhases = (" << "\n"
944 << varGlue("QMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", ",\n")
945 << varGlue("QMAKE_PBX_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
946 << "\t\t\t" << ");" << "\n"
947 << "\t\t\t" << "buildSettings = {" << "\n"
948 << "\t\t\t\t" << "CC = \"" << fixEnvsList("QMAKE_CC") << "\";" << "\n"
949 << "\t\t\t\t" << "CPLUSPLUS = \"" << fixEnvsList("QMAKE_CXX") << "\";" << "\n"
950 << "\t\t\t\t" << "FRAMEWORK_SEARCH_PATHS = \"\";" << "\n"
951 << "\t\t\t\t" << "HEADER_SEARCH_PATHS = \"" << fixEnvsList("INCLUDEPATH") << " " << fixEnvs(specdir()) << "\";" << "\n"
952 << "\t\t\t\t" << "LIBRARY_SEARCH_PATHS = \"" << var("QMAKE_PBX_LIBPATHS") << "\";" << "\n"
953 << "\t\t\t\t" << "OPTIMIZATION_CFLAGS = \"\";" << "\n"
954 << "\t\t\t\t" << "OTHER_CFLAGS = \"" <<
955 fixEnvsList("QMAKE_CFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") <<
956 varGlue("DEFINES"," -D"," -D","") << "\";" << "\n"
957 << "\t\t\t\t" << "LEXFLAGS = \"" << var("QMAKE_LEXFLAGS") << "\";" << "\n"
958 << "\t\t\t\t" << "YACCFLAGS = \"" << var("QMAKE_YACCFLAGS") << "\";" << "\n"
959 << "\t\t\t\t" << "OTHER_CPLUSPLUSFLAGS = \"" <<
960 fixEnvsList("QMAKE_CXXFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") <<
961 varGlue("DEFINES"," -D"," -D","") << "\";" << "\n"
962 << "\t\t\t\t" << "OTHER_REZFLAGS = \"\";" << "\n"
963 << "\t\t\t\t" << "SECTORDER_FLAGS = \"\";" << "\n"
964 << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n"
965 << "\t\t\t\t" << "PREBINDING = " << (project->isEmpty("QMAKE_DO_PREBINDING") ? "NO" : "YES") << ";" << "\n";
966 if(!project->isEmpty("PRECOMPILED_HEADER")) {
967 if (ideType() == MAC_XCODE) {
968 t << "\t\t\t\t" << "GCC_PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n"
969 << "\t\t\t\t" << "GCC_PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n";
970 } else {
971 t << "\t\t\t\t" << "PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n"
972 << "\t\t\t\t" << "PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n";
973 }
974 }
975 if(project->first("TEMPLATE") == "app") {
976 QString file = Option::mkfile::qmakespec + Option::dir_sep + "Info.plist.app";
977 if(QFile::exists(file)) {
978 QFile plist_in_file(file);
979 if(plist_in_file.open(IO_ReadOnly)) {
980 QTextStream plist_in(&plist_in_file);
981 QString plist_in_text = plist_in.read();
982 if(!project->isEmpty("RC_FILE"))
983 plist_in_text = plist_in_text.replace("application.icns", project->first("RC_FILE").section(Option::dir_sep, -1));
984 QFile plist_out_file("Info.plist");
985 if(plist_out_file.open(IO_WriteOnly | IO_Translate)) {
986 QTextStream plist_out(&plist_out_file);
987 plist_out << plist_in_text;
988 t << "\t\t\t\t" << "INFOPLIST_FILE = \"Info.plist\";" << "\n";
989 }
990 }
991 }
992 }
993#if 1
994 t << "\t\t\t\t" << "BUILD_ROOT = \"" << QDir::currentDirPath() << "\";" << "\n";
995#endif
996 if(!project->isActiveConfig("staticlib"))
997 t << "\t\t\t\t" << "OTHER_LDFLAGS = \"" << fixEnvsList("SUBLIBS") << " " <<
998 fixEnvsList("QMAKE_LFLAGS") << " " << fixEnvsList("QMAKE_LIBDIR_FLAGS") <<
999 " " << fixEnvsList("QMAKE_LIBS") << "\";" << "\n";
1000 if(!project->isEmpty("DESTDIR")) {
1001 QString dir = project->first("DESTDIR");
1002 if (QDir::isRelativePath(dir))
1003 dir.prepend(QDir::currentDirPath() + Option::dir_sep);
1004 t << "\t\t\t\t" << "INSTALL_DIR = \"" << dir << "\";" << "\n";
1005 }
1006 if ( project->first("TEMPLATE") == "lib") {
1007 t << "\t\t\t\t" << "INSTALL_PATH = \"" << "\";" << "\n";
1008 }
1009 if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") {
1010 t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VER_MAJ") << "."
1011 << project->first("VER_MIN") << "." << project->first("VER_PAT") << "\";" << "\n";
1012 if(project->isEmpty("COMPAT_VERSION"))
1013 t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("VER_MAJ") << "."
1014 << project->first("VER_MIN") << "\";" << "\n";
1015 }
1016 if(!project->isEmpty("COMPAT_VERSION"))
1017 t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("COMPAT_VERSION") << "\";" << "\n";
1018
1019 if(ideType() == MAC_XCODE) {
1020 if(!project->isEmpty("OBJECTS_DIR"))
1021 t << "\t\t\t\t" << "OBJROOT = \"" << project->first("OBJECTS_DIR") << "\";" << "\n";
1022 }
1023#if 0
1024 if(!project->isEmpty("DESTDIR"))
1025 t << "\t\t\t\t" << "SYMROOT = \"" << project->first("DESTDIR") << "\";" << "\n";
1026 else
1027 t << "\t\t\t\t" << "SYMROOT = \"" << QDir::currentDirPath() << "\";" << "\n";
1028#endif
1029 if(project->first("TEMPLATE") == "app") {
1030 if(ideType() == MAC_PBUILDER && !project->isActiveConfig("console"))
1031 t << "\t\t\t\t" << "WRAPPER_EXTENSION = app;" << "\n";
1032 t << "\t\t\t\t" << "PRODUCT_NAME = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n";
1033 } else {
1034 if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) {
1035 t << "\t\t\t\t" << "LIBRARY_STYLE = STATIC;" << "\n";
1036 } else {
1037 t << "\t\t\t\t" << "LIBRARY_STYLE = DYNAMIC;" << "\n";
1038 }
1039 QString lib = project->first("QMAKE_ORIG_TARGET");
1040 if (!project->isActiveConfig("frameworklib")) {
1041 lib.prepend("lib");
1042 }
1043 t << "\t\t\t\t" << "PRODUCT_NAME = " << lib << ";" << "\n";
1044 }
1045 tmp = project->variables()["QMAKE_PBX_VARS"];
1046 for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) {
1047 QString var = (*it), val = getenv(var);
1048 if(!val && var == "TB")
1049 val = "/usr/bin/";
1050 t << "\t\t\t\t" << var << " = \"" << val << "\";" << "\n";
1051 }
1052 t << "\t\t\t" << "};" << "\n"
1053 << "\t\t\t" << "conditionalBuildSettings = {" << "\n"
1054 << "\t\t\t" << "};" << "\n"
1055 << "\t\t\t" << "dependencies = (" << "\n"
1056 << varGlue("QMAKE_PBX_TARGET_DEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
1057 << "\t\t\t" << ");" << "\n"
1058 << "\t\t\t" << "productReference = " << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << ";" << "\n"
1059 << "\t\t\t" << "shouldUseHeadermap = 1;" << "\n";
1060 if(ideType() == MAC_XCODE)
1061 t << "\t\t\t" << "isa = PBXNativeTarget;" << "\n";
1062 if(project->first("TEMPLATE") == "app") {
1063 if(project->isActiveConfig("console")) {
1064 if(ideType() == MAC_XCODE)
1065 t << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n";
1066 else
1067 t << "\t\t\t" << "isa = PBXToolTarget;" << "\n";
1068 } else {
1069 if(ideType() == MAC_XCODE)
1070 t << "\t\t\t" << "productType = \"com.apple.product-type.application\";" << "\n";
1071 else
1072 t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n";
1073 t << "\t\t\t" << "productSettingsXML = " << "\"" << "<?xml version="
1074 << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n"
1075 << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/"
1076 << "Library/DTDs/PropertyList.dtd\\\">" << "\n"
1077 << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n"
1078 << "\t\t\t\t" << "<dict>" << "\n"
1079 << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n"
1080 << "\t\t\t\t\t" << "<string>English</string>" << "\n"
1081 << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n"
1082 << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n"
1083 << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n"
1084 << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n"
1085 << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n"
1086 << "\t\t\t\t\t" << "<string>6.0</string>" << "\n"
1087 << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n"
1088 << "\t\t\t\t\t" << "<string>APPL</string>" << "\n"
1089 << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n"
1090 //Although the output below looks strange it is to avoid the trigraph ??<
1091 << "\t\t\t\t\t" << "<string>????" << "</string>" << "\n"
1092 << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n"
1093 << "\t\t\t\t\t" << "<string>0.1</string>" << "\n"
1094 << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n"
1095 << "\t\t\t\t\t" << "<true/>" << "\n"
1096 << "\t\t\t\t" << "</dict>" << "\n"
1097 << "\t\t\t\t" << "</plist>" << "\";" << "\n";
1098
1099 }
1100 t << "\t\t\t" << "name = \"" << project->first("QMAKE_ORIG_TARGET") << "\";" << "\n"
1101 << "\t\t\t" << "productName = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n";
1102 } else {
1103 QString lib = project->first("QMAKE_ORIG_TARGET");
1104 if(!project->isActiveConfig("frameworklib"))
1105 lib.prepend("lib");
1106 t << "\t\t\t" << "name = \"" << lib << "\";" << "\n"
1107 << "\t\t\t" << "productName = " << lib << ";" << "\n";
1108 if(ideType() == MAC_XCODE) {
1109 t << "\t\t\t" << "productType = \"com.apple.product-type.library.dynamic\";" << "\n";
1110 //t << "\t\t\t" << "productType = \"com.apple.product-type.library.static\";" << "\n";
1111 } else {
1112 t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n";
1113 }
1114 }
1115 t << "\t\t\t" << "startupPath = \"<<ProjectDirectory>>\";" << "\n";
1116 if(!project->isEmpty("DESTDIR"))
1117 t << "\t\t\t" << "productInstallPath = \"" << project->first("DESTDIR") << "\";" << "\n";
1118 t << "\t\t" << "};" << "\n";
1119 //DEBUG/RELEASE
1120 QString active_buildstyle;
1121#if 0
1122 for(int as_release = 0; as_release < 2; as_release++)
1123#else
1124 bool as_release = !project->isActiveConfig("debug");
1125#endif
1126 {
1127 QString key = keyFor("QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG"));
1128 if(project->isActiveConfig("debug") != as_release)
1129 active_buildstyle = key;
1130 project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key);
1131 t << "\t\t" << key << " = {" << "\n"
1132 << "\t\t\t" << "buildRules = (" << "\n"
1133 << "\t\t\t" << ");" << "\n"
1134 << "\t\t\t" << "buildSettings = {" << "\n"
1135 << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n";
1136 if(as_release) {
1137 t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n";
1138 } else {
1139 t << "\t\t\t\t" << "GCC_ENABLE_FIX_AND_CONTINUE = YES;" << "\n"
1140 << "\t\t\t\t" << "GCC_GENERATE_DEBUGGING_SYMBOLS = YES;" << "\n"
1141 << "\t\t\t\t" << "GCC_OPTIMIZATION_LEVEL = 0;" << "\n"
1142 << "\t\t\t\t" << "ZERO_LINK = YES;" << "\n";
1143 }
1144 t << "\t\t\t" << "};" << "\n"
1145 << "\t\t\t" << "isa = PBXBuildStyle;" << "\n"
1146 << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n"
1147 << "\t\t" << "};" << "\n";
1148 }
1149 //ROOT
1150 t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n"
1151 << "\t\t\t" << "buildStyles = (" << "\n"
1152 << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
1153 << "\t\t\t" << ");" << "\n"
1154 << "\t\t\t" << "hasScannedForEncodings = 1;" << "\n"
1155 << "\t\t\t" << "isa = PBXProject;" << "\n"
1156 << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n"
1157 << "\t\t\t" << "projectDirPath = \"\";" << "\n"
1158 << "\t\t\t" << "targets = (" << "\n"
1159 << "\t\t\t\t" << keyFor("QMAKE_PBX_TARGET") << "\n"
1160 << "\t\t\t" << ");" << "\n"
1161 << "\t\t" << "};" << "\n";
1162
1163 //FOOTER
1164 t << "\t" << "};" << "\n"
1165 << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n"
1166 << "}" << endl;
1167
1168 if(project->isActiveConfig("generate_pbxbuild_makefile")) {
1169 QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
1170 QDir::currentDirPath());
1171 QFile mkwrapf(mkwrap);
1172 if(mkwrapf.open(IO_WriteOnly | IO_Translate)) {
1173 debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1());
1174 QTextStream mkwrapt(&mkwrapf);
1175 writeHeader(mkwrapt);
1176 const char *cleans = "uiclean mocclean preprocess_clean ";
1177 mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n"
1178 << "all:" << "\n\t"
1179 << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n"
1180 << "install: all" << "\n\t"
1181 << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n"
1182 << "distclean clean: preprocess_clean" << "\n\t"
1183 << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " clean" << "\n"
1184 << (!did_preprocess ? cleans : "") << ":" << "\n";
1185 if(did_preprocess)
1186 mkwrapt << cleans << ":" << "\n\t"
1187 << "make -f "
1188 << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl;
1189 }
1190 }
1191 return TRUE;
1192}
1193
1194QString
1195ProjectBuilderMakefileGenerator::fixEnvs(const QString &file)
1196{
1197 QRegExp reg_var("\\$\\((.*)\\)");
1198 for(int rep = 0; (rep = reg_var.search(file, rep)) != -1; ) {
1199 if(project->variables()["QMAKE_PBX_VARS"].findIndex(reg_var.cap(1)) == -1)
1200 project->variables()["QMAKE_PBX_VARS"].append(reg_var.cap(1));
1201 rep += reg_var.matchedLength();
1202 }
1203 return file;
1204}
1205
1206QString
1207ProjectBuilderMakefileGenerator::fixEnvsList(const QString &where)
1208{
1209 QString ret;
1210 const QStringList &l = project->variables()[where];
1211 for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
1212 fixEnvs((*it));
1213 if(!ret.isEmpty())
1214 ret += " ";
1215 ret += (*it);
1216 }
1217 return ret;
1218}
1219
1220QString
1221ProjectBuilderMakefileGenerator::keyFor(const QString &block)
1222{
1223#if 1 //This make this code much easier to debug..
1224 if(project->isActiveConfig("no_pb_munge_key"))
1225 return block;
1226#endif
1227 QString ret;
1228 if(!keys.contains(block)) {
1229 ret = qtMD5(block.utf8()).left(24).upper();
1230 keys.insert(block, ret);
1231 } else {
1232 ret = keys[block];
1233 }
1234 return ret;
1235}
1236
1237bool
1238ProjectBuilderMakefileGenerator::openOutput(QFile &file) const
1239{
1240 if(QDir::isRelativePath(file.name()))
1241 file.setName(Option::output_dir + file.name()); //pwd when qmake was run
1242 QFileInfo fi(file);
1243 if(fi.extension() != "pbxproj" || file.name().isEmpty()) {
1244 QString output = file.name();
1245 if(fi.isDir())
1246 output += QDir::separator();
1247 if(!output.endsWith(projectSuffix())) {
1248 if(file.name().isEmpty() || fi.isDir())
1249 output += project->first("TARGET");
1250 output += projectSuffix() + QDir::separator();
1251 } else if(output[(int)output.length() - 1] != QDir::separator()) {
1252 output += QDir::separator();
1253 }
1254 output += QString("project.pbxproj");
1255 file.setName(output);
1256 }
1257 bool ret = UnixMakefileGenerator::openOutput(file);
1258 ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
1259 Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
1260 return ret;
1261}
1262
1263/* This function is such a hack it is almost pointless, but it
1264 eliminates the warning message from ProjectBuilder that the project
1265 file is for an older version. I guess this could be used someday if
1266 the format of the output is dependant upon the version of
1267 ProjectBuilder as well.
1268*/
1269int
1270ProjectBuilderMakefileGenerator::pbuilderVersion() const
1271{
1272 QString ret;
1273 if(project->isEmpty("QMAKE_PBUILDER_VERSION")) {
1274 QString version, version_plist = project->first("QMAKE_PBUILDER_VERSION_PLIST");
1275 if(version_plist.isEmpty()) {
1276 if(ideType() == MAC_XCODE && QFile::exists("/Developer/Applications/Xcode.app/Contents/version.plist"))
1277 version_plist = "/Developer/Applications/Xcode.app/Contents/version.plist";
1278 else
1279 version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist";
1280 } else {
1281 version_plist = version_plist.replace(QRegExp("\""), "");
1282 }
1283 QFile version_file(version_plist);
1284 if(version_file.open(IO_ReadOnly)) {
1285 debug_msg(1, "pbuilder: version.plist: Reading file: %s", version_plist.latin1());
1286 QTextStream plist(&version_file);
1287
1288 bool in_dict = FALSE;
1289 QString current_key;
1290 QRegExp keyreg("^<key>(.*)</key>$"), stringreg("^<string>(.*)</string>$");
1291 while(!plist.eof()) {
1292 QString line = plist.readLine().stripWhiteSpace();
1293 if(line == "<dict>")
1294 in_dict = TRUE;
1295 else if(line == "</dict>")
1296 in_dict = FALSE;
1297 else if(in_dict) {
1298 if(keyreg.exactMatch(line))
1299 current_key = keyreg.cap(1);
1300 else if(current_key == "CFBundleShortVersionString" && stringreg.exactMatch(line))
1301 version = stringreg.cap(1);
1302 }
1303 }
1304 version_file.close();
1305 } else { debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1()); }
1306 if(version_plist.contains("Xcode")) {
1307 ret = "39";
1308 } else {
1309 if(version.startsWith("2."))
1310 ret = "38";
1311 else if(version == "1.1")
1312 ret = "34";
1313 }
1314 } else {
1315 ret = project->first("QMAKE_PBUILDER_VERSION");
1316 }
1317 if(!ret.isEmpty()) {
1318 bool ok;
1319 int int_ret = ret.toInt(&ok);
1320 if(ok) {
1321 debug_msg(1, "pbuilder: version.plist: Got version: %d", int_ret);
1322 return int_ret;
1323 }
1324 }
1325 debug_msg(1, "pbuilder: version.plist: Fallback to default version");
1326 return 34; //my fallback
1327}
1328
1329int
1330ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where)
1331{
1332 int ret = 0; //absolute is the default..
1333 if(QDir::isRelativePath(where))
1334 ret = 4; //relative
1335 return ret;
1336}
1337
1338ProjectBuilderMakefileGenerator::IDE_TYPE
1339ProjectBuilderMakefileGenerator::ideType() const
1340{
1341 if(!project->isActiveConfig("no_pbx_xcode") &&
1342 (QFile::exists("/Developer/Applications/Xcode.app") || project->isActiveConfig("pbx_xcode")))
1343 return ProjectBuilderMakefileGenerator::MAC_XCODE;
1344 return ProjectBuilderMakefileGenerator::MAC_PBUILDER;
1345}
1346
1347QString
1348ProjectBuilderMakefileGenerator::projectSuffix() const
1349{
1350 if(ideType() == MAC_XCODE)
1351 return ".xcode";
1352 return ".pbproj";
1353}
1354
1355QString
1356ProjectBuilderMakefileGenerator::pbxbuild()
1357{
1358 if(QFile::exists("/usr/bin/pbbuild"))
1359 return "pbbuild";
1360 if(QFile::exists("/usr/bin/xcodebuild"))
1361 return "xcodebuild";
1362 return (ideType() == MAC_XCODE ? "xcodebuild" : "pbxbuild");
1363}
Note: See TracBrowser for help on using the repository browser.