|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the qmake application of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "pbuilder_pbx.h" |
|
43 #include "option.h" |
|
44 #include "meta.h" |
|
45 #include <qdir.h> |
|
46 #include <qregexp.h> |
|
47 #include <qcryptographichash.h> |
|
48 #include <qdebug.h> |
|
49 #include <stdlib.h> |
|
50 #include <time.h> |
|
51 #ifdef Q_OS_UNIX |
|
52 # include <sys/types.h> |
|
53 # include <sys/stat.h> |
|
54 #endif |
|
55 #ifdef Q_OS_DARWIN |
|
56 #include <ApplicationServices/ApplicationServices.h> |
|
57 #include <private/qcore_mac_p.h> |
|
58 #endif |
|
59 |
|
60 QT_BEGIN_NAMESPACE |
|
61 |
|
62 //#define GENERATE_AGGREGRATE_SUBDIR |
|
63 |
|
64 // Note: this is fairly hacky, but it does the job... |
|
65 |
|
66 static QString qtMD5(const QByteArray &src) |
|
67 { |
|
68 QByteArray digest = QCryptographicHash::hash(src, QCryptographicHash::Md5); |
|
69 return QString::fromLatin1(digest.toHex()); |
|
70 } |
|
71 |
|
72 ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator() : UnixMakefileGenerator() |
|
73 { |
|
74 |
|
75 } |
|
76 |
|
77 bool |
|
78 ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t) |
|
79 { |
|
80 writingUnixMakefileGenerator = false; |
|
81 if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) { |
|
82 /* for now just dump, I need to generated an empty xml or something.. */ |
|
83 fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", |
|
84 var("QMAKE_FAILED_REQUIREMENTS").toLatin1().constData()); |
|
85 return true; |
|
86 } |
|
87 |
|
88 project->values("MAKEFILE").clear(); |
|
89 project->values("MAKEFILE").append("Makefile"); |
|
90 if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") |
|
91 return writeMakeParts(t); |
|
92 else if(project->first("TEMPLATE") == "subdirs") |
|
93 return writeSubDirs(t); |
|
94 return false; |
|
95 } |
|
96 |
|
97 struct ProjectBuilderSubDirs { |
|
98 QMakeProject *project; |
|
99 QString subdir; |
|
100 bool autoDelete; |
|
101 ProjectBuilderSubDirs(QMakeProject *p, QString s, bool a=true) : project(p), subdir(s), autoDelete(a) { } |
|
102 ~ProjectBuilderSubDirs() { |
|
103 if(autoDelete) |
|
104 delete project; |
|
105 } |
|
106 }; |
|
107 |
|
108 bool |
|
109 ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) |
|
110 { |
|
111 if(project->isActiveConfig("generate_pbxbuild_makefile")) { |
|
112 QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), |
|
113 qmake_getpwd()); |
|
114 QFile mkwrapf(mkwrap); |
|
115 if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) { |
|
116 if (Option::mkfile::listgen) { |
|
117 generatePrint(fileInfo(mkwrapf.fileName()).absoluteFilePath()); |
|
118 } |
|
119 debug_msg(1, "pbuilder: Creating file: %s", mkwrap.toLatin1().constData()); |
|
120 QTextStream mkwrapt(&mkwrapf); |
|
121 writingUnixMakefileGenerator = true; |
|
122 UnixMakefileGenerator::writeSubDirs(mkwrapt); |
|
123 writingUnixMakefileGenerator = false; |
|
124 } |
|
125 } |
|
126 |
|
127 //HEADER |
|
128 const int pbVersion = pbuilderVersion(); |
|
129 t << "// !$*UTF8*$!" << "\n" |
|
130 << "{" << "\n" |
|
131 << "\t" << writeSettings("archiveVersion", "1", SettingsNoQuote) << ";" << "\n" |
|
132 << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" |
|
133 << "\t" << writeSettings("objectVersion", QString::number(pbVersion), SettingsNoQuote) << ";" << "\n" |
|
134 << "\t" << "objects = {" << endl; |
|
135 |
|
136 //SUBDIRS |
|
137 QList<ProjectBuilderSubDirs*> pb_subdirs; |
|
138 pb_subdirs.append(new ProjectBuilderSubDirs(project, QString(), false)); |
|
139 QString oldpwd = qmake_getpwd(); |
|
140 QMap<QString, QStringList> groups; |
|
141 for(int pb_subdir = 0; pb_subdir < pb_subdirs.size(); ++pb_subdir) { |
|
142 ProjectBuilderSubDirs *pb = pb_subdirs[pb_subdir]; |
|
143 const QStringList subdirs = pb->project->values("SUBDIRS"); |
|
144 for(int subdir = 0; subdir < subdirs.count(); subdir++) { |
|
145 QString tmp = subdirs[subdir]; |
|
146 if(!pb->project->isEmpty(tmp + ".file")) |
|
147 tmp = pb->project->first(tmp + ".file"); |
|
148 else if(!pb->project->isEmpty(tmp + ".subdir")) |
|
149 tmp = pb->project->first(tmp + ".subdir"); |
|
150 if(fileInfo(tmp).isRelative() && !pb->subdir.isEmpty()) { |
|
151 QString subdir = pb->subdir; |
|
152 if(!subdir.endsWith(Option::dir_sep)) |
|
153 subdir += Option::dir_sep; |
|
154 tmp = subdir + tmp; |
|
155 } |
|
156 QFileInfo fi(fileInfo(Option::fixPathToLocalOS(tmp, true))); |
|
157 if(fi.exists()) { |
|
158 if(fi.isDir()) { |
|
159 QString profile = tmp; |
|
160 if(!profile.endsWith(Option::dir_sep)) |
|
161 profile += Option::dir_sep; |
|
162 profile += fi.baseName() + Option::pro_ext; |
|
163 fi = QFileInfo(profile); |
|
164 } |
|
165 QMakeProject tmp_proj; |
|
166 QString dir = fi.path(), fn = fi.fileName(); |
|
167 if(!dir.isEmpty()) { |
|
168 if(!qmake_setpwd(dir)) |
|
169 fprintf(stderr, "Cannot find directory: %s\n", dir.toLatin1().constData()); |
|
170 } |
|
171 if(tmp_proj.read(fn)) { |
|
172 if(Option::debug_level) { |
|
173 QMap<QString, QStringList> &vars = tmp_proj.variables(); |
|
174 for(QMap<QString, QStringList>::Iterator it = vars.begin(); |
|
175 it != vars.end(); ++it) { |
|
176 if(it.key().left(1) != "." && !it.value().isEmpty()) |
|
177 debug_msg(1, "%s: %s === %s", fn.toLatin1().constData(), it.key().toLatin1().constData(), |
|
178 it.value().join(" :: ").toLatin1().constData()); |
|
179 } |
|
180 } |
|
181 if(tmp_proj.first("TEMPLATE") == "subdirs") { |
|
182 QMakeProject *pp = new QMakeProject(&tmp_proj); |
|
183 pp->read(0); |
|
184 pb_subdirs += new ProjectBuilderSubDirs(pp, dir); |
|
185 } else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") { |
|
186 QString pbxproj = qmake_getpwd() + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix(); |
|
187 if(!exists(pbxproj)) { |
|
188 warn_msg(WarnLogic, "Ignored (not found) '%s'", pbxproj.toLatin1().constData()); |
|
189 goto nextfile; // # Dirty! |
|
190 } |
|
191 const QString project_key = keyFor(pbxproj + "_PROJECTREF"); |
|
192 project->values("QMAKE_PBX_SUBDIRS") += pbxproj; |
|
193 //PROJECTREF |
|
194 { |
|
195 bool in_root = true; |
|
196 QString name = qmake_getpwd(); |
|
197 if(project->isActiveConfig("flat")) { |
|
198 QString flat_file = fileFixify(name, oldpwd, Option::output_dir, FileFixifyRelative); |
|
199 if(flat_file.indexOf(Option::dir_sep) != -1) { |
|
200 QStringList dirs = flat_file.split(Option::dir_sep); |
|
201 name = dirs.back(); |
|
202 } |
|
203 } else { |
|
204 QString flat_file = fileFixify(name, oldpwd, Option::output_dir, FileFixifyRelative); |
|
205 if(QDir::isRelativePath(flat_file) && flat_file.indexOf(Option::dir_sep) != -1) { |
|
206 QString last_grp("QMAKE_SUBDIR_PBX_HEIR_GROUP"); |
|
207 QStringList dirs = flat_file.split(Option::dir_sep); |
|
208 name = dirs.back(); |
|
209 for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { |
|
210 QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); |
|
211 if(dir_it == dirs.begin()) { |
|
212 if(!groups.contains(new_grp)) |
|
213 project->values("QMAKE_SUBDIR_PBX_GROUPS").append(new_grp_key); |
|
214 } else { |
|
215 if(!groups[last_grp].contains(new_grp_key)) |
|
216 groups[last_grp] += new_grp_key; |
|
217 } |
|
218 last_grp = new_grp; |
|
219 } |
|
220 groups[last_grp] += project_key; |
|
221 in_root = false; |
|
222 } |
|
223 } |
|
224 if(in_root) |
|
225 project->values("QMAKE_SUBDIR_PBX_GROUPS") += project_key; |
|
226 t << "\t\t" << project_key << " = {" << "\n" |
|
227 << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" |
|
228 << "\t\t\t" << writeSettings("lastKnownFileType", "wrapper.pb-project") << ";" << "\n" |
|
229 << "\t\t\t" << writeSettings("name", escapeFilePath(tmp_proj.first("TARGET") + projectSuffix())) << ";" << "\n" |
|
230 << "\t\t\t" << writeSettings("path", pbxproj) << ";" << "\n" |
|
231 << "\t\t\t" << writeSettings("refType", "0", SettingsNoQuote) << ";" << "\n" |
|
232 << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";" << "\n" |
|
233 << "\t\t" << "};" << "\n"; |
|
234 //WRAPPER |
|
235 t << "\t\t" << keyFor(pbxproj + "_WRAPPER") << " = {" << "\n" |
|
236 << "\t\t\t" << writeSettings("isa", "PBXReferenceProxy", SettingsNoQuote) << ";" << "\n"; |
|
237 if(tmp_proj.first("TEMPLATE") == "app") { |
|
238 t << "\t\t\t" << writeSettings("fileType", "wrapper.application") << ";" << "\n" |
|
239 << "\t\t\t" << writeSettings("path", tmp_proj.first("TARGET") + ".app") << ";" << "\n"; |
|
240 } else { |
|
241 t << "\t\t\t" << writeSettings("fileType", "compiled.mach-o.dylib") << ";" << "\n" |
|
242 << "\t\t\t" << writeSettings("path", tmp_proj.first("TARGET") + ".dylib") << ";" << "\n"; |
|
243 } |
|
244 t << "\t\t\t" << writeSettings("refType", "3", SettingsNoQuote) << ";" << "\n" |
|
245 << "\t\t\t" << writeSettings("remoteRef", keyFor(pbxproj + "_WRAPPERREF")) << ";" << "\n" |
|
246 << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";" << "\n" |
|
247 << "\t\t" << "};" << "\n"; |
|
248 t << "\t\t" << keyFor(pbxproj + "_WRAPPERREF") << " = {" << "\n" |
|
249 << "\t\t\t" << writeSettings("containerPortal", project_key) << ";" << "\n" |
|
250 << "\t\t\t" << writeSettings("isa", "PBXContainerItemProxy", SettingsNoQuote) << ";" << "\n" |
|
251 << "\t\t\t" << writeSettings("proxyType", "2") << ";" << "\n" |
|
252 // << "\t\t\t" << writeSettings("remoteGlobalIDString", keyFor(pbxproj + "QMAKE_PBX_REFERENCE")) << ";" << "\n" |
|
253 << "\t\t\t" << writeSettings("remoteGlobalIDString", keyFor(pbxproj + "QMAKE_PBX_REFERENCE!!!")) << ";" << "\n" |
|
254 << "\t\t\t" << writeSettings("remoteInfo", tmp_proj.first("TARGET")) << ";" << "\n" |
|
255 << "\t\t" << "};" << "\n"; |
|
256 //PRODUCTGROUP |
|
257 t << "\t\t" << keyFor(pbxproj + "_PRODUCTGROUP") << " = {" << "\n" |
|
258 << "\t\t\t" << writeSettings("children", project->values(pbxproj + "_WRAPPER"), SettingsAsList, 4) << ";" << "\n" |
|
259 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
260 << "\t\t\t" << writeSettings("name", "Products") << ";" << "\n" |
|
261 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
262 << "\t\t\t" << writeSettings("sourceTree", "<group>") << ";" << "\n" |
|
263 << "\t\t" << "};" << "\n"; |
|
264 } |
|
265 #ifdef GENERATE_AGGREGRATE_SUBDIR |
|
266 //TARGET (for aggregate) |
|
267 { |
|
268 //container |
|
269 const QString container_proxy = keyFor(pbxproj + "_CONTAINERPROXY"); |
|
270 t << "\t\t" << container_proxy << " = {" << "\n" |
|
271 << "\t\t\t" << writeSettings("containerPortal", project_key) << ";" << "\n" |
|
272 << "\t\t\t" << writeSettings("isa", "PBXContainerItemProxy", SettingsNoQuote) << ";" << "\n" |
|
273 << "\t\t\t" << writeSettings("proxyType", "1") << ";" << "\n" |
|
274 << "\t\t\t" << writeSettings("remoteGlobalIDString", keyFor(pbxproj + "QMAKE_PBX_TARGET")) << ";" << "\n" |
|
275 << "\t\t\t" << writeSettings("remoteInfo", tmp_proj.first("TARGET")) << ";" << "\n" |
|
276 << "\t\t" << "};" << "\n"; |
|
277 //targetref |
|
278 t << "\t\t" << keyFor(pbxproj + "_TARGETREF") << " = {" << "\n" |
|
279 << "\t\t\t" << writeSettings("isa", "PBXTargetDependency", SettingsNoQuote) << ";" << "\n" |
|
280 << "\t\t\t" << writeSettings("name", fixForOutput(tmp_proj.first("TARGET") +" (from " + tmp_proj.first("TARGET") + projectSuffix() + ")")) << ";" << "\n" |
|
281 << "\t\t\t" << writeSettings("targetProxy", container_proxy) << ";" << "\n" |
|
282 << "\t\t" << "};" << "\n"; |
|
283 } |
|
284 #endif |
|
285 } |
|
286 } |
|
287 nextfile: |
|
288 qmake_setpwd(oldpwd); |
|
289 } |
|
290 } |
|
291 } |
|
292 qDeleteAll(pb_subdirs); |
|
293 pb_subdirs.clear(); |
|
294 |
|
295 for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) { |
|
296 t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n" |
|
297 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
298 << "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";" << "\n" |
|
299 << "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";" << "\n" |
|
300 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
301 << "\t\t" << "};" << "\n"; |
|
302 } |
|
303 |
|
304 //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER |
|
305 //BUILDSTYLE |
|
306 QString active_buildstyle; |
|
307 for(int as_release = 0; as_release < 2; as_release++) |
|
308 { |
|
309 QMap<QString, QString> settings; |
|
310 settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); |
|
311 if(as_release) |
|
312 settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO"); |
|
313 if(project->isActiveConfig("sdk") && !project->isEmpty("QMAKE_MAC_SDK")) |
|
314 settings.insert("SDKROOT", project->first("QMAKE_MAC_SDK")); |
|
315 { |
|
316 const QStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS"); |
|
317 for(int i = 0; i < l.size(); ++i) { |
|
318 QString name = l.at(i); |
|
319 const QString value = project->values(name + QLatin1String(".value")).join(QString(Option::field_sep)); |
|
320 if(!project->isEmpty(name + QLatin1String(".name"))) |
|
321 name = project->values(name + QLatin1String(".name")).first(); |
|
322 settings.insert(name, value); |
|
323 } |
|
324 } |
|
325 |
|
326 QString name; |
|
327 if(pbVersion >= 42) |
|
328 name = (as_release ? "Release" : "Debug"); |
|
329 else |
|
330 name = (as_release ? "Deployment" : "Development"); |
|
331 if(pbVersion >= 42) { |
|
332 QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + name); |
|
333 project->values("QMAKE_SUBDIR_PBX_BUILDCONFIGS").append(key); |
|
334 t << "\t\t" << key << " = {" << "\n" |
|
335 << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";" << "\n" |
|
336 << "\t\t\t" << "buildSettings = {" << "\n"; |
|
337 for(QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) |
|
338 t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";" << "\n"; |
|
339 t << "\t\t\t" << "};" << "\n" |
|
340 << "\t\t\t" << writeSettings("name", name) << ";" << "\n" |
|
341 << "\t\t" << "};" << "\n"; |
|
342 } |
|
343 |
|
344 QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDSTYLE_" + name); |
|
345 if(project->isActiveConfig("debug") != (bool)as_release) { |
|
346 project->values("QMAKE_SUBDIR_PBX_BUILDSTYLES").append(key); |
|
347 active_buildstyle = name; |
|
348 } else if(pbVersion >= 42) { |
|
349 project->values("QMAKE_SUBDIR_PBX_BUILDSTYLES").append(key); |
|
350 } |
|
351 t << "\t\t" << key << " = {" << "\n" |
|
352 << "\t\t\t" << writeSettings("buildRules", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
353 << "\t\t\t" << "buildSettings = {" << "\n"; |
|
354 for(QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) |
|
355 t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n"; |
|
356 t << "\t\t\t" << "};" << "\n" |
|
357 << "\t\t\t" << writeSettings("isa", "PBXBuildStyle", SettingsNoQuote) << ";" << "\n" |
|
358 << "\t\t\t" << writeSettings("name", name) << ";" << "\n" |
|
359 << "\t\t" << "};" << "\n"; |
|
360 } |
|
361 if(pbVersion >= 42) { |
|
362 t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_LIST") << " = {" << "\n" |
|
363 << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n" |
|
364 << "\t\t\t" << writeSettings("buildConfigurations", project->values("QMAKE_SUBDIR_PBX_BUILDCONFIGS"), SettingsAsList, 4) << ";" << "\n" |
|
365 << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n" |
|
366 << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n" |
|
367 << "\t\t" << "};" << "\n"; |
|
368 } |
|
369 |
|
370 #ifdef GENERATE_AGGREGRATE_SUBDIR |
|
371 //target |
|
372 t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_AGGREGATE_TARGET") << " = {" << "\n" |
|
373 << "\t\t\t" << writeSettings("buildPhases", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
374 << "\t\t\t" << "buildSettings = {" << "\n" |
|
375 << "\t\t\t\t" << writeSettings("PRODUCT_NAME", project->values("TARGET").first()) << ";" << "\n" |
|
376 << "\t\t\t" << "};" << "\n"; |
|
377 { |
|
378 QStringList dependencies; |
|
379 const QStringList &qmake_subdirs = project->values("QMAKE_PBX_SUBDIRS"); |
|
380 for(int i = 0; i < qmake_subdirs.count(); i++) |
|
381 dependencies += keyFor(qmake_subdirs[i] + "_TARGETREF"); |
|
382 t << "\t\t\t" << writeSettings("dependencies", dependencies, SettingsAsList, 4) << ";" << "\n" |
|
383 } |
|
384 t << "\t\t\t" << writeSettings("isa", "PBXAggregateTarget", SettingsNoQuote) << ";" << "\n" |
|
385 << "\t\t\t" << writeSettings("name", project->values("TARGET").first()) << ";" << "\n" |
|
386 << "\t\t\t" << writeSettings("productName", project->values("TARGET").first()) << ";" << "\n" |
|
387 << "\t\t" << "};" << "\n"; |
|
388 #endif |
|
389 |
|
390 //ROOT_GROUP |
|
391 t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_ROOT_GROUP") << " = {" << "\n" |
|
392 << "\t\t\t" << writeSettings("children", project->values("QMAKE_SUBDIR_PBX_GROUPS"), SettingsAsList, 4) << ";" << "\n" |
|
393 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
394 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
395 << "\t\t\t" << writeSettings("sourceTree", "<group>") << ";" << "\n" |
|
396 << "\t\t" << "};" << "\n"; |
|
397 |
|
398 |
|
399 //ROOT |
|
400 t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_ROOT") << " = {" << "\n" |
|
401 << "\t\t\t" << "buildSettings = {" << "\n" |
|
402 << "\t\t\t" << "};" << "\n" |
|
403 << "\t\t\t" << writeSettings("buildStyles", project->values("QMAKE_SUBDIR_PBX_BUILDSTYLES"), SettingsAsList, 4) << ";" << "\n" |
|
404 << "\t\t\t" << writeSettings("isa", "PBXProject", SettingsNoQuote) << ";" << "\n" |
|
405 << "\t\t\t" << writeSettings("mainGroup", keyFor("QMAKE_SUBDIR_PBX_ROOT_GROUP")) << ";" << "\n" |
|
406 << "\t\t\t" << writeSettings("projectDirPath", QStringList()) << ";" << "\n"; |
|
407 if(pbVersion >= 42) |
|
408 t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_LIST")) << ";" << "\n"; |
|
409 t << "\t\t\t" << "projectReferences = (" << "\n"; |
|
410 { |
|
411 QStringList &qmake_subdirs = project->values("QMAKE_PBX_SUBDIRS"); |
|
412 for(int i = 0; i < qmake_subdirs.count(); i++) { |
|
413 QString subdir = qmake_subdirs[i]; |
|
414 t << "\t\t\t\t" << "{" << "\n" |
|
415 << "\t\t\t\t\t" << writeSettings("ProductGroup", keyFor(subdir + "_PRODUCTGROUP")) << ";" << "\n" |
|
416 << "\t\t\t\t\t" << writeSettings("ProjectRef", keyFor(subdir + "_PROJECTREF")) << ";" << "\n" |
|
417 << "\t\t\t\t" << "}," << "\n"; |
|
418 } |
|
419 } |
|
420 t << "\t\t\t" << ");" << "\n" |
|
421 << "\t\t\t" << writeSettings("targets", |
|
422 #ifdef GENERATE_AGGREGRATE_SUBDIR |
|
423 project->values("QMAKE_SUBDIR_AGGREGATE_TARGET"), |
|
424 #else |
|
425 QStringList(), |
|
426 #endif |
|
427 SettingsAsList, 4) << ";" << "\n" |
|
428 << "\t\t" << "};" << "\n"; |
|
429 |
|
430 //FOOTER |
|
431 t << "\t" << "};" << "\n" |
|
432 << "\t" << writeSettings("rootObject", keyFor("QMAKE_SUBDIR_PBX_ROOT")) << ";" << "\n" |
|
433 << "}" << endl; |
|
434 |
|
435 return true; |
|
436 } |
|
437 |
|
438 class ProjectBuilderSources |
|
439 { |
|
440 bool buildable, object_output; |
|
441 QString key, group, compiler; |
|
442 public: |
|
443 ProjectBuilderSources(const QString &key, bool buildable=false, const QString &group=QString(), const QString &compiler=QString(), bool producesObject=false); |
|
444 QStringList files(QMakeProject *project) const; |
|
445 inline bool isBuildable() const { return buildable; } |
|
446 inline QString keyName() const { return key; } |
|
447 inline QString groupName() const { return group; } |
|
448 inline QString compilerName() const { return compiler; } |
|
449 inline bool isObjectOutput(const QString &file) const { |
|
450 bool ret = object_output; |
|
451 for(int i = 0; !ret && i < Option::c_ext.size(); ++i) { |
|
452 if(file.endsWith(Option::c_ext.at(i))) { |
|
453 ret = true; |
|
454 break; |
|
455 } |
|
456 } |
|
457 for(int i = 0; !ret && i < Option::cpp_ext.size(); ++i) { |
|
458 if(file.endsWith(Option::cpp_ext.at(i))) { |
|
459 ret = true; |
|
460 break; |
|
461 } |
|
462 } |
|
463 return ret; |
|
464 } |
|
465 }; |
|
466 |
|
467 ProjectBuilderSources::ProjectBuilderSources(const QString &k, bool b, |
|
468 const QString &g, const QString &c, bool o) : buildable(b), object_output(o), key(k), group(g), compiler(c) |
|
469 { |
|
470 if(group.isNull()) { |
|
471 if(k == "SOURCES") |
|
472 group = "Sources"; |
|
473 else if(k == "HEADERS") |
|
474 group = "Headers"; |
|
475 else if(k == "QMAKE_INTERNAL_INCLUDED_FILES") |
|
476 group = "Sources [qmake]"; |
|
477 else if(k == "GENERATED_SOURCES" || k == "GENERATED_FILES") |
|
478 group = "Temporary Sources"; |
|
479 else |
|
480 fprintf(stderr, "No group available for %s!\n", k.toLatin1().constData()); |
|
481 } |
|
482 } |
|
483 |
|
484 QStringList |
|
485 ProjectBuilderSources::files(QMakeProject *project) const |
|
486 { |
|
487 QStringList ret = project->values(key); |
|
488 if(key == "QMAKE_INTERNAL_INCLUDED_FILES") { |
|
489 QString pfile = project->projectFile(); |
|
490 if(pfile != "(stdin)") |
|
491 ret.prepend(pfile); |
|
492 for(int i = 0; i < ret.size(); ++i) { |
|
493 QStringList newret; |
|
494 if(!ret.at(i).endsWith(Option::prf_ext)) |
|
495 newret.append(ret.at(i)); |
|
496 ret = newret; |
|
497 } |
|
498 } |
|
499 if(key == "SOURCES" && project->first("TEMPLATE") == "app" && !project->isEmpty("ICON")) |
|
500 ret.append(project->first("ICON")); |
|
501 return ret; |
|
502 } |
|
503 |
|
504 |
|
505 bool |
|
506 ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) |
|
507 { |
|
508 QStringList tmp; |
|
509 bool did_preprocess = false; |
|
510 |
|
511 //HEADER |
|
512 const int pbVersion = pbuilderVersion(); |
|
513 t << "// !$*UTF8*$!" << "\n" |
|
514 << "{" << "\n" |
|
515 << "\t" << writeSettings("archiveVersion", "1", SettingsNoQuote) << ";" << "\n" |
|
516 << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" |
|
517 << "\t" << writeSettings("objectVersion", QString::number(pbVersion), SettingsNoQuote) << ";" << "\n" |
|
518 << "\t" << "objects = {" << endl; |
|
519 |
|
520 //MAKE QMAKE equivelant |
|
521 if(!project->isActiveConfig("no_autoqmake") && project->projectFile() != "(stdin)") { |
|
522 QString mkfile = pbx_dir + Option::dir_sep + "qt_makeqmake.mak"; |
|
523 QFile mkf(mkfile); |
|
524 if(mkf.open(QIODevice::WriteOnly | QIODevice::Text)) { |
|
525 writingUnixMakefileGenerator = true; |
|
526 if (Option::mkfile::listgen) { |
|
527 generatePrint(fileInfo(mkf.fileName()).absoluteFilePath()); |
|
528 } |
|
529 debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData()); |
|
530 QTextStream mkt(&mkf); |
|
531 writeHeader(mkt); |
|
532 mkt << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? |
|
533 QString((QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmake")) : |
|
534 var("QMAKE_QMAKE")) << endl; |
|
535 writeMakeQmake(mkt); |
|
536 mkt.flush(); |
|
537 mkf.close(); |
|
538 writingUnixMakefileGenerator = false; |
|
539 } |
|
540 QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE"); |
|
541 mkfile = fileFixify(mkfile, qmake_getpwd()); |
|
542 project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key); |
|
543 t << "\t\t" << phase_key << " = {" << "\n" |
|
544 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
545 << "\t\t\t" << writeSettings("files", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
546 << "\t\t\t" << writeSettings("generatedFileNames", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
547 << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
548 << "\t\t\t" << writeSettings("name", "Qt Qmake") << ";" << "\n" |
|
549 << "\t\t\t" << writeSettings("neededFileNames", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
550 << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n" |
|
551 << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f " + escapeFilePath(mkfile))) << ";" << "\n" |
|
552 << "\t\t" << "};" << "\n"; |
|
553 } |
|
554 |
|
555 //DUMP SOURCES |
|
556 QMap<QString, QStringList> groups; |
|
557 QList<ProjectBuilderSources> sources; |
|
558 sources.append(ProjectBuilderSources("SOURCES", true)); |
|
559 sources.append(ProjectBuilderSources("GENERATED_SOURCES", true)); |
|
560 sources.append(ProjectBuilderSources("GENERATED_FILES")); |
|
561 sources.append(ProjectBuilderSources("HEADERS")); |
|
562 sources.append(ProjectBuilderSources("QMAKE_INTERNAL_INCLUDED_FILES")); |
|
563 if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) { |
|
564 const QStringList &quc = project->values("QMAKE_EXTRA_COMPILERS"); |
|
565 for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { |
|
566 QString tmp_out = project->first((*it) + ".output"); |
|
567 if(project->isEmpty((*it) + ".output")) |
|
568 continue; |
|
569 QString name = (*it); |
|
570 if(!project->isEmpty((*it) + ".name")) |
|
571 name = project->first((*it) + ".name"); |
|
572 const QStringList &inputs = project->values((*it) + ".input"); |
|
573 for(int input = 0; input < inputs.size(); ++input) { |
|
574 if(project->isEmpty(inputs.at(input))) |
|
575 continue; |
|
576 bool duplicate = false; |
|
577 for(int i = 0; i < sources.size(); ++i) { |
|
578 if(sources.at(i).keyName() == inputs.at(input)) { |
|
579 duplicate = true; |
|
580 break; |
|
581 } |
|
582 } |
|
583 if(!duplicate) { |
|
584 bool isObj = project->values((*it) + ".CONFIG").indexOf("no_link") == -1; |
|
585 const QStringList &outputs = project->values((*it) + ".variable_out"); |
|
586 for(int output = 0; output < outputs.size(); ++output) { |
|
587 if(outputs.at(output) != "OBJECT") { |
|
588 isObj = false; |
|
589 break; |
|
590 } |
|
591 } |
|
592 sources.append(ProjectBuilderSources(inputs.at(input), true, |
|
593 QString("Sources [") + name + "]", (*it), isObj)); |
|
594 } |
|
595 } |
|
596 } |
|
597 } |
|
598 for(int source = 0; source < sources.size(); ++source) { |
|
599 QStringList &src_list = project->values("QMAKE_PBX_" + sources.at(source).keyName()); |
|
600 QStringList &root_group_list = project->values("QMAKE_PBX_GROUPS"); |
|
601 |
|
602 QStringList files = fileFixify(sources.at(source).files(project)); |
|
603 for(int f = 0; f < files.count(); ++f) { |
|
604 QString file = files[f]; |
|
605 if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0]) |
|
606 file = file.mid(1, file.length()-2); |
|
607 if(!sources.at(source).compilerName().isNull() && |
|
608 !verifyExtraCompiler(sources.at(source).compilerName(), file)) |
|
609 continue; |
|
610 if(file.endsWith(Option::prl_ext)) |
|
611 continue; |
|
612 |
|
613 bool in_root = true; |
|
614 QString src_key = keyFor(file), name = file; |
|
615 if(project->isActiveConfig("flat")) { |
|
616 QString flat_file = fileFixify(file, qmake_getpwd(), Option::output_dir, FileFixifyRelative); |
|
617 if(flat_file.indexOf(Option::dir_sep) != -1) { |
|
618 QStringList dirs = flat_file.split(Option::dir_sep); |
|
619 name = dirs.back(); |
|
620 } |
|
621 } else { |
|
622 QString flat_file = fileFixify(file, qmake_getpwd(), Option::output_dir, FileFixifyRelative); |
|
623 if(QDir::isRelativePath(flat_file) && flat_file.indexOf(Option::dir_sep) != -1) { |
|
624 QString last_grp("QMAKE_PBX_" + sources.at(source).groupName() + "_HEIR_GROUP"); |
|
625 QStringList dirs = flat_file.split(Option::dir_sep); |
|
626 name = dirs.back(); |
|
627 dirs.pop_back(); //remove the file portion as it will be added via src_key |
|
628 for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { |
|
629 QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); |
|
630 if(dir_it == dirs.begin()) { |
|
631 if(!src_list.contains(new_grp_key)) |
|
632 src_list.append(new_grp_key); |
|
633 } else { |
|
634 if(!groups[last_grp].contains(new_grp_key)) |
|
635 groups[last_grp] += new_grp_key; |
|
636 } |
|
637 last_grp = new_grp; |
|
638 } |
|
639 groups[last_grp] += src_key; |
|
640 in_root = false; |
|
641 } |
|
642 } |
|
643 if(in_root) |
|
644 src_list.append(src_key); |
|
645 //source reference |
|
646 t << "\t\t" << src_key << " = {" << "\n" |
|
647 << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" |
|
648 << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";" << "\n" |
|
649 << "\t\t\t" << writeSettings("path", escapeFilePath(file)) << ";" << "\n" |
|
650 << "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(file)), SettingsNoQuote) << ";" << "\n"; |
|
651 if(pbVersion >= 38) { |
|
652 QString filetype; |
|
653 for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { |
|
654 if(file.endsWith((*cppit))) { |
|
655 filetype = "sourcecode.cpp.cpp"; |
|
656 break; |
|
657 } |
|
658 } |
|
659 if(!filetype.isNull()) |
|
660 t << "\t\t\t" << writeSettings("lastKnownFileType", filetype) << ";" << "\n"; |
|
661 } |
|
662 t << "\t\t" << "};" << "\n"; |
|
663 if(sources.at(source).isBuildable()) { //build reference |
|
664 QString build_key = keyFor(file + ".BUILDABLE"); |
|
665 t << "\t\t" << build_key << " = {" << "\n" |
|
666 << "\t\t\t" << writeSettings("fileRef", src_key) << ";" << "\n" |
|
667 << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" |
|
668 << "\t\t\t" << "settings = {" << "\n" |
|
669 << "\t\t\t\t" << writeSettings("ATTRIBUTES", QStringList(), SettingsAsList, 5) << ";" << "\n" |
|
670 << "\t\t\t" << "};" << "\n" |
|
671 << "\t\t" << "};" << "\n"; |
|
672 if(sources.at(source).isObjectOutput(file)) |
|
673 project->values("QMAKE_PBX_OBJ").append(build_key); |
|
674 } |
|
675 } |
|
676 if(!src_list.isEmpty()) { |
|
677 QString group_key = keyFor(sources.at(source).groupName()); |
|
678 if(root_group_list.indexOf(group_key) == -1) |
|
679 root_group_list += group_key; |
|
680 |
|
681 QStringList &group = groups[sources.at(source).groupName()]; |
|
682 for(int src = 0; src < src_list.size(); ++src) { |
|
683 if(group.indexOf(src_list.at(src)) == -1) |
|
684 group += src_list.at(src); |
|
685 } |
|
686 } |
|
687 } |
|
688 for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) { |
|
689 t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n" |
|
690 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
691 << "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";" << "\n" |
|
692 << "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";" << "\n" |
|
693 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
694 << "\t\t" << "};" << "\n"; |
|
695 } |
|
696 |
|
697 //PREPROCESS BUILDPHASE (just a makefile) |
|
698 { |
|
699 QString mkfile = pbx_dir + Option::dir_sep + "qt_preprocess.mak"; |
|
700 QFile mkf(mkfile); |
|
701 if(mkf.open(QIODevice::WriteOnly | QIODevice::Text)) { |
|
702 writingUnixMakefileGenerator = true; |
|
703 did_preprocess = true; |
|
704 if (Option::mkfile::listgen) { |
|
705 generatePrint(fileInfo(mkf.fileName()).absoluteFilePath()); |
|
706 } |
|
707 debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData()); |
|
708 QTextStream mkt(&mkf); |
|
709 writeHeader(mkt); |
|
710 mkt << "MOC = " << Option::fixPathToTargetOS(var("QMAKE_MOC")) << endl; |
|
711 mkt << "UIC = " << Option::fixPathToTargetOS(var("QMAKE_UIC")) << endl; |
|
712 mkt << "LEX = " << var("QMAKE_LEX") << endl; |
|
713 mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl; |
|
714 mkt << "YACC = " << var("QMAKE_YACC") << endl; |
|
715 mkt << "YACCFLAGS = " << var("QMAKE_YACCFLAGS") << endl; |
|
716 mkt << "DEFINES = " |
|
717 << varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ") |
|
718 << varGlue("DEFINES","-D"," -D","") << endl; |
|
719 mkt << "INCPATH = " << "-I" << specdir(); |
|
720 if(!project->isActiveConfig("no_include_pwd")) { |
|
721 QString pwd = escapeFilePath(fileFixify(qmake_getpwd())); |
|
722 if(pwd.isEmpty()) |
|
723 pwd = "."; |
|
724 mkt << " -I" << pwd; |
|
725 } |
|
726 { |
|
727 const QStringList &incs = project->values("INCLUDEPATH"); |
|
728 for(QStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit) |
|
729 mkt << " " << "-I" << escapeFilePath((*incit)); |
|
730 } |
|
731 if(!project->isEmpty("QMAKE_FRAMEWORKPATH_FLAGS")) |
|
732 mkt << " " << var("QMAKE_FRAMEWORKPATH_FLAGS"); |
|
733 mkt << endl; |
|
734 mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; |
|
735 mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl; |
|
736 mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl; |
|
737 mkt << "PARSERS ="; |
|
738 if(!project->isEmpty("YACCSOURCES")) { |
|
739 QStringList &yaccs = project->values("YACCSOURCES"); |
|
740 for(QStringList::Iterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) { |
|
741 QFileInfo fi(fileInfo((*yit))); |
|
742 mkt << " " << fi.path() << Option::dir_sep << fi.baseName() |
|
743 << Option::yacc_mod << Option::cpp_ext.first(); |
|
744 } |
|
745 } |
|
746 if(!project->isEmpty("LEXSOURCES")) { |
|
747 QStringList &lexs = project->values("LEXSOURCES"); |
|
748 for(QStringList::Iterator lit = lexs.begin(); lit != lexs.end(); ++lit) { |
|
749 QFileInfo fi(fileInfo((*lit))); |
|
750 mkt << " " << fi.path() << Option::dir_sep << fi.baseName() |
|
751 << Option::lex_mod << Option::cpp_ext.first(); |
|
752 } |
|
753 } |
|
754 mkt << "\n"; |
|
755 mkt << "preprocess: $(PARSERS) compilers" << endl; |
|
756 mkt << "clean preprocess_clean: parser_clean compiler_clean" << endl << endl; |
|
757 mkt << "parser_clean:" << "\n"; |
|
758 if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) |
|
759 mkt << "\t-rm -f $(PARSERS)" << "\n"; |
|
760 writeExtraTargets(mkt); |
|
761 if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) { |
|
762 mkt << "compilers:"; |
|
763 const QStringList &compilers = project->values("QMAKE_EXTRA_COMPILERS"); |
|
764 for(int compiler = 0; compiler < compilers.size(); ++compiler) { |
|
765 QString tmp_out = project->first(compilers.at(compiler) + ".output"); |
|
766 if(project->isEmpty(compilers.at(compiler) + ".output")) |
|
767 continue; |
|
768 const QStringList &inputs = project->values(compilers.at(compiler) + ".input"); |
|
769 for(int input = 0; input < inputs.size(); ++input) { |
|
770 if(project->isEmpty(inputs.at(input))) |
|
771 continue; |
|
772 const QStringList &files = project->values(inputs.at(input)); |
|
773 for(int file = 0, added = 0; file < files.size(); ++file) { |
|
774 if(!verifyExtraCompiler(compilers.at(compiler), files.at(file))) |
|
775 continue; |
|
776 if(added && !(added % 3)) |
|
777 mkt << "\\\n\t"; |
|
778 ++added; |
|
779 const QString file_name = fileFixify(files.at(file), Option::output_dir, Option::output_dir); |
|
780 mkt << " " << replaceExtraCompilerVariables(tmp_out, file_name, QString()); |
|
781 } |
|
782 } |
|
783 } |
|
784 mkt << endl; |
|
785 writeExtraCompilerTargets(mkt); |
|
786 writingUnixMakefileGenerator = false; |
|
787 } |
|
788 mkt.flush(); |
|
789 mkf.close(); |
|
790 } |
|
791 mkfile = fileFixify(mkfile, qmake_getpwd()); |
|
792 QString phase_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET"); |
|
793 // project->values("QMAKE_PBX_BUILDPHASES").append(phase_key); |
|
794 project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key); |
|
795 t << "\t\t" << phase_key << " = {" << "\n" |
|
796 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
797 << "\t\t\t" << writeSettings("files", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
798 << "\t\t\t" << writeSettings("generatedFileNames", fixListForOutput("QMAKE_PBX_OBJ"), SettingsAsList, 4) << ";" << "\n" |
|
799 << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
800 << "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";" << "\n" |
|
801 << "\t\t\t" << writeSettings("neededFileNames", fixListForOutput("QMAKE_PBX_OBJ"), SettingsAsList, 4) << ";" << "\n" |
|
802 << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n" |
|
803 << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f " + escapeFilePath(mkfile))) << ";" << "\n" |
|
804 << "\t\t" << "};" << "\n"; |
|
805 } |
|
806 |
|
807 //SOURCE BUILDPHASE |
|
808 if(!project->isEmpty("QMAKE_PBX_OBJ")) { |
|
809 QString grp = "Build Sources", key = keyFor(grp); |
|
810 project->values("QMAKE_PBX_BUILDPHASES").append(key); |
|
811 t << "\t\t" << key << " = {" << "\n" |
|
812 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
813 << "\t\t\t" << writeSettings("files", fixListForOutput("QMAKE_PBX_OBJ"), SettingsAsList, 4) << ";" << "\n" |
|
814 << "\t\t\t" << writeSettings("isa", "PBXSourcesBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
815 << "\t\t\t" << writeSettings("name", grp) << ";" << "\n" |
|
816 << "\t\t" << "};" << "\n"; |
|
817 } |
|
818 |
|
819 if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES |
|
820 QStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"), |
|
821 &frameworkdirs = project->values("QMAKE_FRAMEWORKPATH"); |
|
822 QString libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS", |
|
823 "QMAKE_LIBS", QString() }; |
|
824 for(int i = 0; !libs[i].isNull(); i++) { |
|
825 tmp = project->values(libs[i]); |
|
826 for(int x = 0; x < tmp.count();) { |
|
827 bool remove = false; |
|
828 QString library, name, opt = tmp[x].trimmed(); |
|
829 if(opt.length() >= 2 && (opt[0] == '"' || opt[0] == '\'') && |
|
830 opt[(int) opt.length()-1] == opt[0]) |
|
831 opt = opt.mid(1, opt.length()-2); |
|
832 if(opt.startsWith("-L")) { |
|
833 QString r = opt.right(opt.length() - 2); |
|
834 fixForOutput(r); |
|
835 libdirs.append(r); |
|
836 } else if(opt == "-prebind") { |
|
837 project->values("QMAKE_DO_PREBINDING").append("TRUE"); |
|
838 remove = true; |
|
839 } else if(opt.startsWith("-l")) { |
|
840 name = opt.right(opt.length() - 2); |
|
841 QString lib("lib" + name); |
|
842 for(QStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) { |
|
843 if(project->isActiveConfig("link_prl")) { |
|
844 /* This isn't real nice, but it is real useful. This looks in a prl |
|
845 for what the library will ultimately be called so we can stick it |
|
846 in the ProjectFile. If the prl format ever changes (not likely) then |
|
847 this will not really work. However, more concerning is that it will |
|
848 encode the version number in the Project file which might be a bad |
|
849 things in days to come? --Sam |
|
850 */ |
|
851 QString lib_file = (*lit) + Option::dir_sep + lib; |
|
852 if(QMakeMetaInfo::libExists(lib_file)) { |
|
853 QMakeMetaInfo libinfo; |
|
854 if(libinfo.readLib(lib_file)) { |
|
855 if(!libinfo.isEmpty("QMAKE_PRL_TARGET")) { |
|
856 library = (*lit) + Option::dir_sep + libinfo.first("QMAKE_PRL_TARGET"); |
|
857 debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)", |
|
858 opt.toLatin1().constData(), lib_file.toLatin1().constData(), library.toLatin1().constData()); |
|
859 remove = true; |
|
860 } |
|
861 } |
|
862 } |
|
863 } |
|
864 if(!remove) { |
|
865 QString extns[] = { ".dylib", ".so", ".a", QString() }; |
|
866 for(int n = 0; !remove && !extns[n].isNull(); n++) { |
|
867 QString tmp = (*lit) + Option::dir_sep + lib + extns[n]; |
|
868 if(exists(tmp)) { |
|
869 library = tmp; |
|
870 debug_msg(1, "pbuilder: Found library (%s) via %s", |
|
871 opt.toLatin1().constData(), library.toLatin1().constData()); |
|
872 remove = true; |
|
873 } |
|
874 } |
|
875 } |
|
876 } |
|
877 } else if(opt.startsWith("-F")) { |
|
878 QString r; |
|
879 if(opt.size() > 2) { |
|
880 r = opt.right(opt.length() - 2); |
|
881 } else { |
|
882 if(x == tmp.count()-1) |
|
883 break; |
|
884 r = tmp[++x]; |
|
885 } |
|
886 if(!r.isEmpty()) { |
|
887 fixForOutput(r); |
|
888 frameworkdirs.append(r); |
|
889 } |
|
890 } else if(opt == "-framework") { |
|
891 if(x == tmp.count()-1) |
|
892 break; |
|
893 const QString framework = tmp[x+1]; |
|
894 QStringList fdirs = frameworkdirs; |
|
895 fdirs << "/System/Library/Frameworks/" << "/Library/Frameworks/"; |
|
896 for(int fdir = 0; fdir < fdirs.count(); fdir++) { |
|
897 if(exists(fdirs[fdir] + QDir::separator() + framework + ".framework")) { |
|
898 tmp.removeAt(x); |
|
899 remove = true; |
|
900 library = fdirs[fdir] + Option::dir_sep + framework + ".framework"; |
|
901 break; |
|
902 } |
|
903 } |
|
904 } else if(opt.left(1) != "-") { |
|
905 if(exists(opt)) { |
|
906 remove = true; |
|
907 library = opt; |
|
908 } |
|
909 } |
|
910 if(!library.isEmpty()) { |
|
911 const int slsh = library.lastIndexOf(Option::dir_sep); |
|
912 if(name.isEmpty()) { |
|
913 if(slsh != -1) |
|
914 name = library.right(library.length() - slsh - 1); |
|
915 } |
|
916 if(slsh != -1) { |
|
917 const QString path = QFileInfo(library.left(slsh)).absoluteFilePath(); |
|
918 if(!path.isEmpty() && !libdirs.contains(path)) |
|
919 libdirs += path; |
|
920 } |
|
921 library = fileFixify(library); |
|
922 QString key = keyFor(library); |
|
923 bool is_frmwrk = (library.endsWith(".framework")); |
|
924 t << "\t\t" << key << " = {" << "\n" |
|
925 << "\t\t\t" << writeSettings("isa", (is_frmwrk ? "PBXFrameworkReference" : "PBXFileReference"), SettingsNoQuote) << ";" << "\n" |
|
926 << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";" << "\n" |
|
927 << "\t\t\t" << writeSettings("path", escapeFilePath(library)) << ";" << "\n" |
|
928 << "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(library)), SettingsNoQuote) << ";" << "\n" |
|
929 << "\t\t" << "};" << "\n"; |
|
930 project->values("QMAKE_PBX_LIBRARIES").append(key); |
|
931 QString build_key = keyFor(library + ".BUILDABLE"); |
|
932 t << "\t\t" << build_key << " = {" << "\n" |
|
933 << "\t\t\t" << writeSettings("fileRef", key) << ";" << "\n" |
|
934 << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" |
|
935 << "\t\t\t" << "settings = {" << "\n" |
|
936 << "\t\t\t" << "};" << "\n" |
|
937 << "\t\t" << "};" << "\n"; |
|
938 project->values("QMAKE_PBX_BUILD_LIBRARIES").append(build_key); |
|
939 } |
|
940 if(remove) |
|
941 tmp.removeAt(x); |
|
942 else |
|
943 x++; |
|
944 } |
|
945 project->values(libs[i]) = tmp; |
|
946 } |
|
947 } |
|
948 //SUBLIBS BUILDPHASE (just another makefile) |
|
949 if(!project->isEmpty("SUBLIBS")) { |
|
950 QString mkfile = pbx_dir + Option::dir_sep + "qt_sublibs.mak"; |
|
951 QFile mkf(mkfile); |
|
952 if(mkf.open(QIODevice::WriteOnly | QIODevice::Text)) { |
|
953 writingUnixMakefileGenerator = true; |
|
954 if (Option::mkfile::listgen) { |
|
955 generatePrint(fileInfo(mkf.fileName()).absoluteFilePath()); |
|
956 } |
|
957 debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData()); |
|
958 QTextStream mkt(&mkf); |
|
959 writeHeader(mkt); |
|
960 mkt << "SUBLIBS= "; |
|
961 tmp = project->values("SUBLIBS"); |
|
962 for(int i = 0; i < tmp.count(); i++) |
|
963 t << "tmp/lib" << tmp[i] << ".a "; |
|
964 t << endl << endl; |
|
965 mkt << "sublibs: $(SUBLIBS)" << endl << endl; |
|
966 tmp = project->values("SUBLIBS"); |
|
967 for(int i = 0; i < tmp.count(); i++) |
|
968 t << "tmp/lib" << tmp[i] << ".a" << ":\n\t" |
|
969 << var(QString("MAKELIB") + tmp[i]) << endl << endl; |
|
970 mkt.flush(); |
|
971 mkf.close(); |
|
972 writingUnixMakefileGenerator = false; |
|
973 } |
|
974 QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE"); |
|
975 mkfile = fileFixify(mkfile, qmake_getpwd()); |
|
976 project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key); |
|
977 t << "\t\t" << phase_key << " = {" << "\n" |
|
978 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
979 << "\t\t\t" << writeSettings("files", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
980 << "\t\t\t" << writeSettings("generatedFileNames", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
981 << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
982 << "\t\t\t" << writeSettings("name", "Qt Sublibs") << ";" << "\n" |
|
983 << "\t\t\t" << writeSettings("neededFileNames", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
984 << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << "\n" |
|
985 << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f " + escapeFilePath(mkfile))) << ";" << "\n" |
|
986 << "\t\t" << "};" << "\n"; |
|
987 } |
|
988 //LIBRARY BUILDPHASE |
|
989 if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) { |
|
990 tmp = project->values("QMAKE_PBX_LIBRARIES"); |
|
991 if(!tmp.isEmpty()) { |
|
992 QString grp("External Frameworks and Libraries"), key = keyFor(grp); |
|
993 project->values("QMAKE_PBX_GROUPS").append(key); |
|
994 t << "\t\t" << key << " = {" << "\n" |
|
995 << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_LIBRARIES"), SettingsAsList, 4) << ";" << "\n" |
|
996 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
997 << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" |
|
998 << "\t\t\t" << writeSettings("path", QStringList()) << ";" << "\n" |
|
999 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
1000 << "\t\t" << "};" << "\n"; |
|
1001 } |
|
1002 } |
|
1003 { |
|
1004 QString grp("Frameworks & Libraries"), key = keyFor(grp); |
|
1005 project->values("QMAKE_PBX_BUILDPHASES").append(key); |
|
1006 t << "\t\t" << key << " = {" << "\n" |
|
1007 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
1008 << "\t\t\t" << writeSettings("files", project->values("QMAKE_PBX_BUILD_LIBRARIES"), SettingsAsList, 4) << ";" << "\n" |
|
1009 << "\t\t\t" << writeSettings("isa", "PBXFrameworksBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
1010 << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" |
|
1011 << "\t\t" << "};" << "\n"; |
|
1012 } |
|
1013 if(project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES |
|
1014 QString grp("Bundle Resources"), key = keyFor(grp); |
|
1015 project->values("QMAKE_PBX_BUILDPHASES").append(key); |
|
1016 t << "\t\t" << key << " = {" << "\n" |
|
1017 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
1018 << "\t\t\t" << "files = (" << "\n"; |
|
1019 if(!project->isEmpty("ICON")) { |
|
1020 QString icon = project->first("ICON"); |
|
1021 if(icon.length() >= 2 && (icon[0] == '"' || icon[0] == '\'') && icon[(int)icon.length()-1] == icon[0]) |
|
1022 icon = icon.mid(1, icon.length()-2); |
|
1023 t << "\t\t\t\t" << keyFor(icon + ".BUILDABLE") << ",\n"; |
|
1024 } |
|
1025 t << "\t\t\t" << ");" << "\n" |
|
1026 << "\t\t\t" << writeSettings("isa", "PBXResourcesBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
1027 << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" |
|
1028 << "\t\t" << "};" << "\n"; |
|
1029 } |
|
1030 { //INSTALL BUILDPHASE (copy) |
|
1031 QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE"); |
|
1032 QString destDir = Option::output_dir; |
|
1033 if (!project->isEmpty("QMAKE_ORIG_DESTDIR")) |
|
1034 destDir = project->first("QMAKE_ORIG_DESTDIR"); |
|
1035 destDir = fixForOutput(destDir); |
|
1036 destDir = fileInfo(Option::fixPathToLocalOS(destDir)).absoluteFilePath(); |
|
1037 project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key); |
|
1038 t << "\t\t" << phase_key << " = {\n" |
|
1039 << "\t\t\t" << writeSettings("name", "Project Copy") << ";" << "\n" |
|
1040 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
1041 << "\t\t\t" << writeSettings("dstPath", escapeFilePath(destDir)) << ";" << "\n" |
|
1042 << "\t\t\t" << writeSettings("dstSubfolderSpec", "0", SettingsNoQuote) << ";" << "\n" |
|
1043 << "\t\t\t" << writeSettings("files", keyFor("QMAKE_PBX_TARGET_COPY_FILE"), SettingsAsList, 4) << ";" << "\n" |
|
1044 << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
1045 << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" |
|
1046 << "\t\t" << "};\n" |
|
1047 << "\t\t" << keyFor("QMAKE_PBX_TARGET_COPY_FILE") << " = {\n" |
|
1048 << "\t\t\t" << writeSettings("fileRef", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n" |
|
1049 << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" |
|
1050 << "\t\t\t" << "settings = {\n" |
|
1051 << "\t\t\t" << "};\n" |
|
1052 << "\t\t" << "};\n"; |
|
1053 } |
|
1054 //BUNDLE_DATA BUILDPHASE (copy) |
|
1055 if(!project->isEmpty("QMAKE_BUNDLE_DATA")) { |
|
1056 QStringList bundle_file_refs; |
|
1057 //all bundle data |
|
1058 const QStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA"); |
|
1059 for(int i = 0; i < bundle_data.count(); i++) { |
|
1060 QStringList pbx_files; |
|
1061 //all files |
|
1062 const QStringList &files = project->values(bundle_data[i] + ".files"); |
|
1063 for(int file = 0; file < files.count(); file++) { |
|
1064 QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_COPY_FILE_REF." + bundle_data[i] + "-" + files[file]); |
|
1065 bundle_file_refs += file_ref_key; |
|
1066 t << "\t\t" << file_ref_key << " = {" << "\n" |
|
1067 << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" |
|
1068 << "\t\t\t" << writeSettings("path", escapeFilePath(files[file])) << ";" << "\n" |
|
1069 << "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(files[file])), SettingsNoQuote) << ";" << "\n" |
|
1070 << "\t\t" << "};" << "\n"; |
|
1071 QString copy_file_key = keyFor("QMAKE_PBX_BUNDLE_COPY_FILE." + bundle_data[i] + "-" + files[file]); |
|
1072 pbx_files += copy_file_key; |
|
1073 t << "\t\t" << copy_file_key << " = {\n" |
|
1074 << "\t\t\t" << writeSettings("fileRef", file_ref_key) << ";" << "\n" |
|
1075 << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" |
|
1076 << "\t\t\t" << "settings = {\n" |
|
1077 << "\t\t\t" << "}" << ";" << "\n" |
|
1078 << "\t\t" << "}" << ";" << "\n"; |
|
1079 } |
|
1080 //the phase |
|
1081 QString phase_key = keyFor("QMAKE_PBX_BUNDLE_COPY." + bundle_data[i]); |
|
1082 QString path; |
|
1083 if(!project->isEmpty(bundle_data[i] + ".version")) { |
|
1084 //### |
|
1085 } |
|
1086 path += project->first(bundle_data[i] + ".path"); |
|
1087 project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key); |
|
1088 t << "\t\t" << phase_key << " = {\n" |
|
1089 << "\t\t\t" << writeSettings("name", "Bundle Copy [" + bundle_data[i] + "]") << ";" << "\n" |
|
1090 << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" |
|
1091 << "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";" << "\n" |
|
1092 << "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";" << "\n" |
|
1093 << "\t\t\t" << writeSettings("files", pbx_files, SettingsAsList, 4) << ";" << "\n" |
|
1094 << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";" << "\n" |
|
1095 << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" |
|
1096 << "\t\t" << "}" << ";" << "\n"; |
|
1097 } |
|
1098 QString bundle_copy_key = keyFor("QMAKE_PBX_BUNDLE_COPY"); |
|
1099 project->values("QMAKE_PBX_GROUPS").append(bundle_copy_key); |
|
1100 t << "\t\t" << bundle_copy_key << " = {" << "\n" |
|
1101 << "\t\t\t" << writeSettings("children", bundle_file_refs, SettingsAsList, 4) << ";" << "\n" |
|
1102 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
1103 << "\t\t\t" << writeSettings("name", "Source [bundle data]") << ";" << "\n" |
|
1104 << "\t\t\t" << writeSettings("path", QStringList()) << ";" << "\n" |
|
1105 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
1106 << "\t\t" << "};" << "\n"; |
|
1107 } |
|
1108 |
|
1109 if(/*pbVersion >= 38 &&*/ !project->isEmpty("QMAKE_PBX_PRESCRIPT_BUILDPHASES") && 0) { |
|
1110 // build reference |
|
1111 t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPT_BUILDREFERENCE") << " = {" << "\n" |
|
1112 << "\t\t\t" << writeSettings("includeInIndex", "0") << ";" << "\n" |
|
1113 << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" |
|
1114 << "\t\t\t" << writeSettings("path", "preprocessor.out") << ";" << "\n" |
|
1115 << "\t\t\t" << writeSettings("refType", "3", SettingsNoQuote) << ";" << "\n" |
|
1116 << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";" << "\n" |
|
1117 << "\t\t" << "};" << "\n"; |
|
1118 project->values("QMAKE_PBX_PRODUCTS").append(keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE")); |
|
1119 //build phase |
|
1120 t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE") << " = {" << "\n" |
|
1121 << "\t\t\t" << writeSettings("buildPhases", project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES"), SettingsAsList, 4) << ";" << "\n" |
|
1122 << "\t\t\t" << writeSettings("buildRules", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
1123 << "\t\t\t" << writeSettings("buildSettings", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
1124 << "\t\t\t" << writeSettings("dependencies", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
1125 << "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";" << "\n" |
|
1126 << "\t\t\t" << writeSettings("name", "Qt Preprocessor Steps") << ";" << "\n" |
|
1127 << "\t\t\t" << writeSettings("productName", "Qt Preprocessor Steps") << ";" << "\n" |
|
1128 << "\t\t\t" << writeSettings("productReference", keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE")) << ";" << "\n"; |
|
1129 if(!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) |
|
1130 t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n"; |
|
1131 else |
|
1132 t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";" << "\n"; |
|
1133 t << "\t\t" << "};" << "\n"; |
|
1134 //dependency |
|
1135 t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY") << " = {" << "\n" |
|
1136 << "\t\t\t" << writeSettings("isa", "PBXTargetDependency", SettingsNoQuote) << ";" << "\n" |
|
1137 << "\t\t\t" << writeSettings("target", keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE")) << ";" << "\n" |
|
1138 << "\t\t" << "};" << "\n"; |
|
1139 project->values("QMAKE_PBX_TARGET_DEPENDS").append(keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY")); |
|
1140 project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").clear(); //these are already consumed above |
|
1141 } |
|
1142 |
|
1143 //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER |
|
1144 //ROOT_GROUP |
|
1145 t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n" |
|
1146 << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_GROUPS"), SettingsAsList, 4) << ";" << "\n" |
|
1147 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
1148 << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n" |
|
1149 << "\t\t\t" << writeSettings("path", QStringList()) << ";" << "\n" |
|
1150 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
1151 << "\t\t" << "};" << "\n"; |
|
1152 //REFERENCE |
|
1153 project->values("QMAKE_PBX_PRODUCTS").append(keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")); |
|
1154 t << "\t\t" << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << " = {" << "\n" |
|
1155 << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n"; |
|
1156 if(project->first("TEMPLATE") == "app") { |
|
1157 QString targ = project->first("QMAKE_ORIG_TARGET"); |
|
1158 if(project->isActiveConfig("bundle") && !project->isEmpty("QMAKE_BUNDLE_EXTENSION")) { |
|
1159 if(!project->isEmpty("QMAKE_BUNDLE_NAME")) |
|
1160 targ = project->first("QMAKE_BUNDLE_NAME"); |
|
1161 targ += project->first("QMAKE_BUNDLE_EXTENSION"); |
|
1162 if(!project->isEmpty("QMAKE_PBX_BUNDLE_TYPE")) |
|
1163 t << "\t\t\t" << writeSettings("explicitFileType", project->first("QMAKE_PBX_BUNDLE_TYPE")) + ";" << "\n"; |
|
1164 } else if(project->isActiveConfig("app_bundle")) { |
|
1165 if(!project->isEmpty("QMAKE_APPLICATION_BUNDLE_NAME")) |
|
1166 targ = project->first("QMAKE_APPLICATION_BUNDLE_NAME"); |
|
1167 targ += ".app"; |
|
1168 t << "\t\t\t" << writeSettings("explicitFileType", "wrapper.application") << ";" << "\n"; |
|
1169 } else { |
|
1170 t << "\t\t\t" << writeSettings("explicitFileType", "wrapper.executable") << ";" << "\n"; |
|
1171 } |
|
1172 QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") : |
|
1173 qmake_getpwd()) + Option::dir_sep + targ; |
|
1174 t << "\t\t\t" << writeSettings("path", escapeFilePath(targ)) << ";" << "\n"; |
|
1175 } else { |
|
1176 QString lib = project->first("QMAKE_ORIG_TARGET"); |
|
1177 if(project->isActiveConfig("staticlib")) { |
|
1178 lib = project->first("TARGET"); |
|
1179 } else if(!project->isActiveConfig("lib_bundle")) { |
|
1180 if(project->isActiveConfig("plugin")) |
|
1181 lib = project->first("TARGET"); |
|
1182 else |
|
1183 lib = project->first("TARGET_"); |
|
1184 } |
|
1185 int slsh = lib.lastIndexOf(Option::dir_sep); |
|
1186 if(slsh != -1) |
|
1187 lib = lib.right(lib.length() - slsh - 1); |
|
1188 if(project->isActiveConfig("bundle") && !project->isEmpty("QMAKE_BUNDLE_EXTENSION")) { |
|
1189 if(!project->isEmpty("QMAKE_BUNDLE_NAME")) |
|
1190 lib = project->first("QMAKE_BUNDLE_NAME"); |
|
1191 lib += project->first("QMAKE_BUNDLE_EXTENSION"); |
|
1192 if(!project->isEmpty("QMAKE_PBX_BUNDLE_TYPE")) |
|
1193 t << "\t\t\t" << writeSettings("explicitFileType", project->first("QMAKE_PBX_BUNDLE_TYPE")) << ";" << "\n"; |
|
1194 } else if(!project->isActiveConfig("staticlib") && project->isActiveConfig("lib_bundle")) { |
|
1195 if(!project->isEmpty("QMAKE_FRAMEWORK_BUNDLE_NAME")) |
|
1196 lib = project->first("QMAKE_FRAMEWORK_BUNDLE_NAME"); |
|
1197 lib += ".framework"; |
|
1198 t << "\t\t\t" << writeSettings("explicitFileType", "wrapper.framework") << ";" << "\n"; |
|
1199 } else { |
|
1200 t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.dylib") << ";" << "\n"; |
|
1201 } |
|
1202 t << "\t\t\t" << writeSettings("path", escapeFilePath(lib)) << ";" << "\n"; |
|
1203 } |
|
1204 t << "\t\t\t" << writeSettings("refType", "3", SettingsNoQuote) << ";" << "\n" |
|
1205 << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";" << "\n" |
|
1206 << "\t\t" << "};" << "\n"; |
|
1207 { //Products group |
|
1208 QString grp("Products"), key = keyFor(grp); |
|
1209 project->values("QMAKE_PBX_GROUPS").append(key); |
|
1210 t << "\t\t" << key << " = {" << "\n" |
|
1211 << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_PRODUCTS"), SettingsAsList, 4) << ";" << "\n" |
|
1212 << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" |
|
1213 << "\t\t\t" << writeSettings("name", "Products") << ";" << "\n" |
|
1214 << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" |
|
1215 << "\t\t" << "};" << "\n"; |
|
1216 } |
|
1217 //TARGET |
|
1218 QString target_key = keyFor(pbx_dir + "QMAKE_PBX_TARGET"); |
|
1219 project->values("QMAKE_PBX_TARGETS").append(target_key); |
|
1220 t << "\t\t" << target_key << " = {" << "\n" |
|
1221 << "\t\t\t" << writeSettings("buildPhases", project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES") + project->values("QMAKE_PBX_BUILDPHASES"), |
|
1222 SettingsAsList, 4) << ";" << "\n" |
|
1223 << "\t\t\t" << "buildSettings = {" << "\n"; |
|
1224 QString cCompiler = project->first("QMAKE_CC"); |
|
1225 if (!cCompiler.isEmpty()) { |
|
1226 t << "\t\t\t\t" << writeSettings("CC", fixForOutput(findProgram(cCompiler))) << ";" << "\n"; |
|
1227 } |
|
1228 cCompiler = project->first("QMAKE_CXX"); |
|
1229 if (!cCompiler.isEmpty()) { |
|
1230 t << "\t\t\t\t" << writeSettings("CPLUSPLUS", fixForOutput(findProgram(cCompiler))) << ";" << "\n"; |
|
1231 } |
|
1232 |
|
1233 t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + QStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n" |
|
1234 << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n" |
|
1235 << "\t\t\t\t" << writeSettings("OPTIMIZATION_CFLAGS", QStringList(), SettingsAsList, 5) << ";" << "\n"; |
|
1236 { |
|
1237 QStringList cflags = fixListForOutput("QMAKE_CFLAGS"); |
|
1238 const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES"); |
|
1239 for(int i = 0; i < prl_defines.size(); ++i) |
|
1240 cflags += "-D" + prl_defines.at(i); |
|
1241 const QStringList &defines = project->values("DEFINES"); |
|
1242 for(int i = 0; i < defines.size(); ++i) |
|
1243 cflags += "-D" + defines.at(i); |
|
1244 t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";" << "\n"; |
|
1245 } |
|
1246 { |
|
1247 QStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS"); |
|
1248 const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES"); |
|
1249 for(int i = 0; i < prl_defines.size(); ++i) |
|
1250 cxxflags += "-D" + prl_defines.at(i); |
|
1251 const QStringList &defines = project->values("DEFINES"); |
|
1252 for(int i = 0; i < defines.size(); ++i) |
|
1253 cxxflags += "-D" + defines.at(i); |
|
1254 t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";" << "\n"; |
|
1255 } |
|
1256 t << "\t\t\t\t" << writeSettings("LEXFLAGS", fixListForOutput("QMAKE_LEXFLAGS")) << ";" << "\n" |
|
1257 << "\t\t\t\t" << writeSettings("YACCFLAGS", fixListForOutput("QMAKE_YACCFLAGS")) << ";" << "\n" |
|
1258 << "\t\t\t\t" << writeSettings("OTHER_REZFLAGS", QStringList()) << ";" << "\n" |
|
1259 << "\t\t\t\t" << writeSettings("SECTORDER_FLAGS", QStringList()) << ";" << "\n" |
|
1260 << "\t\t\t\t" << writeSettings("WARNING_CFLAGS", QStringList()) << ";" << "\n" |
|
1261 << "\t\t\t\t" << writeSettings("PREBINDING", QStringList((project->isEmpty("QMAKE_DO_PREBINDING") ? "NO" : "YES")), SettingsNoQuote) << ";" << "\n"; |
|
1262 if(!project->isEmpty("PRECOMPILED_HEADER")) { |
|
1263 if(pbVersion >= 38) { |
|
1264 t << "\t\t\t\t" << writeSettings("GCC_PRECOMPILE_PREFIX_HEADER", "YES") << ";" << "\n" |
|
1265 << "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", escapeFilePath(project->first("PRECOMPILED_HEADER"))) << ";" << "\n"; |
|
1266 } else { |
|
1267 t << "\t\t\t\t" << writeSettings("PRECOMPILE_PREFIX_HEADER", "YES") << ";" << "\n" |
|
1268 << "\t\t\t\t" << writeSettings("PREFIX_HEADER", escapeFilePath(project->first("PRECOMPILED_HEADER"))) << ";" << "\n"; |
|
1269 } |
|
1270 } |
|
1271 if((project->first("TEMPLATE") == "app" && project->isActiveConfig("app_bundle")) || |
|
1272 (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && |
|
1273 project->isActiveConfig("lib_bundle"))) { |
|
1274 QString plist = fileFixify(project->first("QMAKE_INFO_PLIST")); |
|
1275 if(plist.isEmpty()) |
|
1276 plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); |
|
1277 if(exists(plist)) { |
|
1278 QFile plist_in_file(plist); |
|
1279 if(plist_in_file.open(QIODevice::ReadOnly)) { |
|
1280 QTextStream plist_in(&plist_in_file); |
|
1281 QString plist_in_text = plist_in.readAll(); |
|
1282 plist_in_text = plist_in_text.replace("@ICON@", |
|
1283 (project->isEmpty("ICON") ? QString("") : project->first("ICON").section(Option::dir_sep, -1))); |
|
1284 if(project->first("TEMPLATE") == "app") { |
|
1285 plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET")); |
|
1286 } else { |
|
1287 plist_in_text = plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET")); |
|
1288 plist_in_text = plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + |
|
1289 project->first("VER_MIN")); |
|
1290 } |
|
1291 plist_in_text = plist_in_text.replace("@TYPEINFO@", |
|
1292 (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : |
|
1293 project->first("QMAKE_PKGINFO_TYPEINFO").left(4))); |
|
1294 QFile plist_out_file("Info.plist"); |
|
1295 if(plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) { |
|
1296 if (Option::mkfile::listgen) { |
|
1297 generatePrint(fileInfo(plist_out_file.fileName()).absoluteFilePath()); |
|
1298 } |
|
1299 QTextStream plist_out(&plist_out_file); |
|
1300 plist_out << plist_in_text; |
|
1301 t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";" << "\n"; |
|
1302 } |
|
1303 } |
|
1304 } |
|
1305 } |
|
1306 #if 1 |
|
1307 t << "\t\t\t\t" << writeSettings("BUILD_ROOT", escapeFilePath(qmake_getpwd())) << ";" << "\n"; |
|
1308 #endif |
|
1309 if(!project->isActiveConfig("staticlib")) { |
|
1310 t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS", |
|
1311 fixListForOutput("SUBLIBS") |
|
1312 + fixListForOutput("QMAKE_LFLAGS") |
|
1313 + fixListForOutput("QMAKE_LIBDIR_FLAGS") |
|
1314 + fixListForOutput("QMAKE_FRAMEWORKPATH_FLAGS") |
|
1315 + fixListForOutput("QMAKE_LIBS"), |
|
1316 SettingsAsList, 6) << ";" << "\n"; |
|
1317 } |
|
1318 if(!project->isEmpty("DESTDIR")) { |
|
1319 QString dir = project->first("DESTDIR"); |
|
1320 if (QDir::isRelativePath(dir)) |
|
1321 dir.prepend(qmake_getpwd() + Option::dir_sep); |
|
1322 t << "\t\t\t\t" << writeSettings("INSTALL_DIR", dir) << ";" << "\n"; |
|
1323 } |
|
1324 if (project->first("TEMPLATE") == "lib") { |
|
1325 t << "\t\t\t\t" << writeSettings("INSTALL_PATH", QStringList()) << ";" << "\n"; |
|
1326 } |
|
1327 if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") { |
|
1328 t << "\t\t\t\t" << writeSettings("DYLIB_CURRENT_VERSION", project->first("VER_MAJ")+"."+project->first("VER_MIN")+"."+project->first("VER_PAT")) << ";" << "\n"; |
|
1329 if(project->isEmpty("COMPAT_VERSION")) |
|
1330 t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("VER_MAJ")+"."+project->first("VER_MIN")) << ";" << "\n"; |
|
1331 if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && |
|
1332 project->isActiveConfig("lib_bundle")) |
|
1333 t << "\t\t\t\t" << writeSettings("FRAMEWORK_VERSION", project->first("QMAKE_FRAMEWORK_VERSION")) << ";" << "\n"; |
|
1334 } |
|
1335 if(!project->isEmpty("COMPAT_FRAMEWORKPATH")) |
|
1336 t << "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"), SettingsAsList, 5) << ";" << "\n"; |
|
1337 if(!project->isEmpty("COMPAT_VERSION")) |
|
1338 t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("COMPAT_VERSION")) << ";" << "\n"; |
|
1339 if(!project->isEmpty("QMAKE_MACOSX_DEPLOYMENT_TARGET")) |
|
1340 t << "\t\t\t\t" << writeSettings("MACOSX_DEPLOYMENT_TARGET", project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET")) << ";" << "\n"; |
|
1341 if(pbVersion >= 38) { |
|
1342 if(!project->isEmpty("OBJECTS_DIR")) |
|
1343 t << "\t\t\t\t" << writeSettings("OBJROOT", fixForOutput(project->first("OBJECTS_DIR"))) << ";" << "\n"; |
|
1344 } |
|
1345 #if 0 |
|
1346 if(!project->isEmpty("DESTDIR")) |
|
1347 t << "\t\t\t\t" << writeSettings("SYMROOT", fixForOutput(project->first("DESTDIR"))) << ";" << "\n"; |
|
1348 else |
|
1349 t << "\t\t\t\t" << writeSettings("SYMROOT", fixForOutput(qmake_getpwd())) << ";" << "\n"; |
|
1350 #endif |
|
1351 { |
|
1352 QStringList archs; |
|
1353 if(project->isActiveConfig("x86")) |
|
1354 archs += "i386"; |
|
1355 if(project->isActiveConfig("ppc")) { |
|
1356 if(!archs.isEmpty()) |
|
1357 archs += " "; |
|
1358 archs += "ppc"; |
|
1359 } |
|
1360 if(project->isActiveConfig("ppc64")) { |
|
1361 if(!archs.isEmpty()) |
|
1362 archs += " "; |
|
1363 archs += "ppc64"; |
|
1364 } |
|
1365 if(project->isActiveConfig("x86_64")) { |
|
1366 if(!archs.isEmpty()) |
|
1367 archs += " "; |
|
1368 archs += "x86_64"; |
|
1369 } |
|
1370 if(!archs.isEmpty()) |
|
1371 t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";" << "\n"; |
|
1372 |
|
1373 } |
|
1374 if(project->first("TEMPLATE") == "app") { |
|
1375 if(pbVersion < 38 && project->isActiveConfig("app_bundle")) |
|
1376 t << "\t\t\t\t" << writeSettings("WRAPPER_SUFFIX", "app") << ";" << "\n"; |
|
1377 t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n"; |
|
1378 } else { |
|
1379 if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) { |
|
1380 t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "STATIC") << ";" << "\n"; |
|
1381 } else { |
|
1382 t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "DYNAMIC") << ";" << "\n"; |
|
1383 } |
|
1384 QString lib = project->first("QMAKE_ORIG_TARGET"); |
|
1385 if(!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib")) |
|
1386 lib.prepend("lib"); |
|
1387 t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", escapeFilePath(lib)) << ";" << "\n"; |
|
1388 } |
|
1389 tmp = project->values("QMAKE_PBX_VARS"); |
|
1390 for(int i = 0; i < tmp.count(); i++) { |
|
1391 QString var = tmp[i], val = qgetenv(var.toLatin1()); |
|
1392 if(val.isEmpty() && var == "TB") |
|
1393 val = "/usr/bin/"; |
|
1394 t << "\t\t\t\t" << writeSettings(var, escapeFilePath(val)) << ";" << "\n"; |
|
1395 } |
|
1396 t << "\t\t\t" << "};" << "\n" |
|
1397 << "\t\t\t" << "conditionalBuildSettings = {" << "\n" |
|
1398 << "\t\t\t" << "};" << "\n" |
|
1399 << "\t\t\t" << writeSettings("dependencies", project->values("QMAKE_PBX_TARGET_DEPENDS"), SettingsAsList, 4) << ";" << "\n" |
|
1400 << "\t\t\t" << writeSettings("productReference", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n" |
|
1401 << "\t\t\t" << writeSettings("shouldUseHeadermap", "1", SettingsNoQuote) << ";" << "\n"; |
|
1402 if(pbVersion >= 38) |
|
1403 t << "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";" << "\n"; |
|
1404 if(project->first("TEMPLATE") == "app") { |
|
1405 if(!project->isActiveConfig("app_bundle")) { |
|
1406 if(pbVersion >= 38) { |
|
1407 if(!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) |
|
1408 t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n"; |
|
1409 else |
|
1410 t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";" << "\n"; |
|
1411 } else { |
|
1412 t << "\t\t\t" << writeSettings("isa", "PBXToolTarget", SettingsNoQuote) << ";" << "\n"; |
|
1413 } |
|
1414 } else { |
|
1415 if(pbVersion >= 38) { |
|
1416 if(!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) |
|
1417 t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n"; |
|
1418 else |
|
1419 t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.application") << ";" << "\n"; |
|
1420 } else { |
|
1421 t << "\t\t\t" << writeSettings("isa", "PBXApplicationTarget", SettingsNoQuote) << ";" << "\n"; |
|
1422 } |
|
1423 t << "\t\t\t" << "productSettingsXML = \""; |
|
1424 bool read_plist = false; |
|
1425 if(exists("Info.plist")) { |
|
1426 QFile plist("Info.plist"); |
|
1427 if (plist.open(QIODevice::ReadOnly)) { |
|
1428 read_plist = true; |
|
1429 QTextStream stream(&plist); |
|
1430 while(!stream.atEnd()) |
|
1431 t << stream.readLine().replace('"', "\\\"") << endl; |
|
1432 } |
|
1433 } |
|
1434 if(!read_plist) { |
|
1435 t << "<?xml version=" |
|
1436 << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n" |
|
1437 << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/" |
|
1438 << "Library/DTDs/PropertyList.dtd\\\">" << "\n" |
|
1439 << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n" |
|
1440 << "\t\t\t\t" << "<dict>" << "\n" |
|
1441 << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n" |
|
1442 << "\t\t\t\t\t" << "<string>English</string>" << "\n" |
|
1443 << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n" |
|
1444 << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n" |
|
1445 << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n" |
|
1446 << "\t\t\t\t\t" << "<string>" << var("ICON").section(Option::dir_sep, -1) << "</string>" << "\n" |
|
1447 << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n" |
|
1448 << "\t\t\t\t\t" << "<string>6.0</string>" << "\n" |
|
1449 << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n" |
|
1450 << "\t\t\t\t\t" << "<string>APPL</string>" << "\n" |
|
1451 << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n" |
|
1452 << "\t\t\t\t\t" << "<string>" |
|
1453 << (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : |
|
1454 project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << "</string>" << "\n" |
|
1455 << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n" |
|
1456 << "\t\t\t\t\t" << "<string>0.1</string>" << "\n" |
|
1457 << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n" |
|
1458 << "\t\t\t\t\t" << "<true/>" << "\n" |
|
1459 << "\t\t\t\t" << "</dict>" << "\n" |
|
1460 << "\t\t\t\t" << "</plist>"; |
|
1461 } |
|
1462 t << "\";" << "\n"; |
|
1463 } |
|
1464 t << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n" |
|
1465 << "\t\t\t" << writeSettings("productName", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n"; |
|
1466 } else { |
|
1467 QString lib = project->first("QMAKE_ORIG_TARGET"); |
|
1468 if(!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib")) |
|
1469 lib.prepend("lib"); |
|
1470 t << "\t\t\t" << writeSettings("name", escapeFilePath(lib)) << ";" << "\n" |
|
1471 << "\t\t\t" << writeSettings("productName", escapeFilePath(lib)) << ";" << "\n"; |
|
1472 if(pbVersion >= 38) { |
|
1473 if(!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) |
|
1474 t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n"; |
|
1475 else if(project->isActiveConfig("staticlib")) |
|
1476 t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.library.static") << ";" << "\n"; |
|
1477 else if(project->isActiveConfig("lib_bundle")) |
|
1478 t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.framework") << ";" << "\n"; |
|
1479 else |
|
1480 t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.library.dynamic") << ";" << "\n"; |
|
1481 } else { |
|
1482 t << "\t\t\t" << writeSettings("isa", "PBXLibraryTarget", SettingsNoQuote) << ";" << "\n"; |
|
1483 } |
|
1484 } |
|
1485 t << "\t\t\t" << writeSettings("startupPath", "<<ProjectDirectory>>") << ";" << "\n"; |
|
1486 if(!project->isEmpty("DESTDIR")) |
|
1487 t << "\t\t\t" << writeSettings("productInstallPath", escapeFilePath(project->first("DESTDIR"))) << ";" << "\n"; |
|
1488 t << "\t\t" << "};" << "\n"; |
|
1489 //DEBUG/RELEASE |
|
1490 QString active_buildstyle; |
|
1491 for(int as_release = 0; as_release < 2; as_release++) |
|
1492 { |
|
1493 QMap<QString, QString> settings; |
|
1494 settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); |
|
1495 settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES"); |
|
1496 if(!as_release) |
|
1497 settings.insert("GCC_OPTIMIZATION_LEVEL", "0"); |
|
1498 if(project->isActiveConfig("sdk") && !project->isEmpty("QMAKE_MAC_SDK")) |
|
1499 settings.insert("SDKROOT", project->first("QMAKE_MAC_SDK")); |
|
1500 { |
|
1501 const QStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS"); |
|
1502 for(int i = 0; i < l.size(); ++i) { |
|
1503 QString name = l.at(i); |
|
1504 const QString value = project->values(name + QLatin1String(".value")).join(QString(Option::field_sep)); |
|
1505 if(!project->isEmpty(name + QLatin1String(".name"))) |
|
1506 name = project->values(name + QLatin1String(".name")).first(); |
|
1507 settings.insert(name, value); |
|
1508 } |
|
1509 } |
|
1510 |
|
1511 QString name; |
|
1512 if(pbVersion >= 42) |
|
1513 name = (as_release ? "Release" : "Debug"); |
|
1514 else |
|
1515 name = (as_release ? "Deployment" : "Development"); |
|
1516 if(pbVersion >= 42) { |
|
1517 QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name); |
|
1518 project->values("QMAKE_PBX_BUILDCONFIGS").append(key); |
|
1519 t << "\t\t" << key << " = {" << "\n" |
|
1520 << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";" << "\n" |
|
1521 << "\t\t\t" << "buildSettings = {" << "\n"; |
|
1522 for(QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) |
|
1523 t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n"; |
|
1524 t << "\t\t\t" << "};" << "\n" |
|
1525 << "\t\t\t" << writeSettings("name", name) << ";" << "\n" |
|
1526 << "\t\t" << "};" << "\n"; |
|
1527 } |
|
1528 |
|
1529 QString key = keyFor("QMAKE_PBX_BUILDSTYLE_" + name); |
|
1530 if(project->isActiveConfig("debug") != (bool)as_release) { |
|
1531 project->values("QMAKE_PBX_BUILDSTYLES").append(key); |
|
1532 active_buildstyle = name; |
|
1533 } else if(pbVersion >= 42) { |
|
1534 project->values("QMAKE_PBX_BUILDSTYLES").append(key); |
|
1535 } |
|
1536 t << "\t\t" << key << " = {" << "\n" |
|
1537 << "\t\t\t" << writeSettings("buildRules", QStringList(), SettingsAsList, 4) << ";" << "\n" |
|
1538 << "\t\t\t" << "buildSettings = {" << "\n"; |
|
1539 for(QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) |
|
1540 t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";" << "\n"; |
|
1541 t << "\t\t\t" << "};" << "\n" |
|
1542 << "\t\t\t" << writeSettings("isa", "PBXBuildStyle") << ";" << "\n" |
|
1543 << "\t\t\t" << writeSettings("name", name) << ";" << "\n" |
|
1544 << "\t\t" << "};" << "\n"; |
|
1545 } |
|
1546 if(pbVersion >= 42) { |
|
1547 t << "\t\t" << keyFor("QMAKE_PBX_BUILDCONFIG_LIST") << " = {" << "\n" |
|
1548 << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n" |
|
1549 << "\t\t\t" << writeSettings("buildConfigurations", project->values("QMAKE_PBX_BUILDCONFIGS"), SettingsAsList, 4) << ";" << "\n" |
|
1550 << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n" |
|
1551 << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n" |
|
1552 << "\t\t" << "};" << "\n"; |
|
1553 } |
|
1554 //ROOT |
|
1555 t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n" |
|
1556 << "\t\t\t" << writeSettings("buildStyles", project->values("QMAKE_PBX_BUILDSTYLES"), SettingsAsList, 4) << ";" << "\n" |
|
1557 << "\t\t\t" << writeSettings("hasScannedForEncodings", "1", SettingsNoQuote) << ";" << "\n" |
|
1558 << "\t\t\t" << writeSettings("isa", "PBXProject", SettingsNoQuote) << ";" << "\n" |
|
1559 << "\t\t\t" << writeSettings("mainGroup", keyFor("QMAKE_PBX_ROOT_GROUP")) << ";" << "\n"; |
|
1560 if(pbVersion >= 42) |
|
1561 t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST")) << ";" << "\n"; |
|
1562 t << "\t\t\t" << writeSettings("projectDirPath", QStringList()) << ";" << "\n" |
|
1563 << "\t\t\t" << writeSettings("targets", project->values("QMAKE_PBX_TARGETS"), SettingsAsList, 4) << ";" << "\n" |
|
1564 << "\t\t" << "};" << "\n"; |
|
1565 |
|
1566 //FOOTER |
|
1567 t << "\t" << "};" << "\n" |
|
1568 << "\t" << writeSettings("rootObject", keyFor("QMAKE_PBX_ROOT")) << ";" << "\n" |
|
1569 << "}" << endl; |
|
1570 |
|
1571 if(project->isActiveConfig("generate_pbxbuild_makefile")) { |
|
1572 QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), |
|
1573 qmake_getpwd()); |
|
1574 QFile mkwrapf(mkwrap); |
|
1575 if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) { |
|
1576 writingUnixMakefileGenerator = true; |
|
1577 if (Option::mkfile::listgen) { |
|
1578 generatePrint(fileInfo(mkwrapf.fileName()).absoluteFilePath()); |
|
1579 } |
|
1580 debug_msg(1, "pbuilder: Creating file: %s", mkwrap.toLatin1().constData()); |
|
1581 QTextStream mkwrapt(&mkwrapf); |
|
1582 writeHeader(mkwrapt); |
|
1583 const char cleans[] = "preprocess_clean "; |
|
1584 mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" |
|
1585 << "all:" << "\n\t" |
|
1586 << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n" |
|
1587 << "install: all" << "\n\t" |
|
1588 << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n" |
|
1589 << "distclean clean: preprocess_clean" << "\n\t" |
|
1590 << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " clean" << "\n" |
|
1591 << (!did_preprocess ? cleans : "") << ":" << "\n"; |
|
1592 if(did_preprocess) |
|
1593 mkwrapt << cleans << ":" << "\n\t" |
|
1594 << "make -f " |
|
1595 << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl; |
|
1596 writingUnixMakefileGenerator = false; |
|
1597 } |
|
1598 } |
|
1599 return true; |
|
1600 } |
|
1601 |
|
1602 QString |
|
1603 ProjectBuilderMakefileGenerator::findProgram(const QString &prog) |
|
1604 { |
|
1605 QString ret = prog; |
|
1606 if(QDir::isRelativePath(ret)) { |
|
1607 QStringList paths = QString(qgetenv("PATH")).split(':'); |
|
1608 for(int i = 0; i < paths.size(); ++i) { |
|
1609 QString path = paths.at(i) + "/" + prog; |
|
1610 if(exists(path)) { |
|
1611 ret = path; |
|
1612 break; |
|
1613 } |
|
1614 } |
|
1615 } |
|
1616 return ret; |
|
1617 } |
|
1618 |
|
1619 QString |
|
1620 ProjectBuilderMakefileGenerator::fixForOutput(const QString &values) |
|
1621 { |
|
1622 //get the environment variables references |
|
1623 QRegExp reg_var("\\$\\((.*)\\)"); |
|
1624 for(int rep = 0; (rep = reg_var.indexIn(values, rep)) != -1;) { |
|
1625 if(project->values("QMAKE_PBX_VARS").indexOf(reg_var.cap(1)) == -1) |
|
1626 project->values("QMAKE_PBX_VARS").append(reg_var.cap(1)); |
|
1627 rep += reg_var.matchedLength(); |
|
1628 } |
|
1629 QString ret = values; |
|
1630 ret = ret.replace(QRegExp("\\\\ "), " "); //unescape spaces |
|
1631 ret = ret.replace(QRegExp("('|\\\\|\")"), "\\\\1"); //fix quotes |
|
1632 ret = ret.replace("\t", " "); //fix tabs |
|
1633 ret = ret.replace(QRegExp(" "), "\\ "); //escape spaces |
|
1634 return ret; |
|
1635 } |
|
1636 |
|
1637 QStringList |
|
1638 ProjectBuilderMakefileGenerator::fixListForOutput(const QString &where) |
|
1639 { |
|
1640 QStringList ret; |
|
1641 const QStringList &l = project->values(where); |
|
1642 for(int i = 0; i < l.count(); i++) |
|
1643 ret += fixForOutput(l[i]); |
|
1644 return ret; |
|
1645 } |
|
1646 |
|
1647 QString |
|
1648 ProjectBuilderMakefileGenerator::keyFor(const QString &block) |
|
1649 { |
|
1650 #if 1 //This make this code much easier to debug.. |
|
1651 if(project->isActiveConfig("no_pb_munge_key")) |
|
1652 return block; |
|
1653 #endif |
|
1654 QString ret; |
|
1655 if(!keys.contains(block)) { |
|
1656 ret = qtMD5(block.toUtf8()).left(24).toUpper(); |
|
1657 keys.insert(block, ret); |
|
1658 } else { |
|
1659 ret = keys[block]; |
|
1660 } |
|
1661 return ret; |
|
1662 } |
|
1663 |
|
1664 bool |
|
1665 ProjectBuilderMakefileGenerator::openOutput(QFile &file, const QString &build) const |
|
1666 { |
|
1667 if(QDir::isRelativePath(file.fileName())) |
|
1668 file.setFileName(Option::output_dir + "/" + file.fileName()); //pwd when qmake was run |
|
1669 QFileInfo fi(fileInfo(file.fileName())); |
|
1670 if(fi.suffix() != "pbxproj" || file.fileName().isEmpty()) { |
|
1671 QString output = file.fileName(); |
|
1672 if(fi.isDir()) |
|
1673 output += QDir::separator(); |
|
1674 if(!output.endsWith(projectSuffix())) { |
|
1675 if(file.fileName().isEmpty() || fi.isDir()) { |
|
1676 if(project->first("TEMPLATE") == "subdirs" || project->isEmpty("QMAKE_ORIG_TARGET")) |
|
1677 output += fileInfo(project->projectFile()).baseName(); |
|
1678 else |
|
1679 output += project->first("QMAKE_ORIG_TARGET"); |
|
1680 } |
|
1681 output += projectSuffix() + QDir::separator(); |
|
1682 } else if(output[(int)output.length() - 1] != QDir::separator()) { |
|
1683 output += QDir::separator(); |
|
1684 } |
|
1685 output += QString("project.pbxproj"); |
|
1686 output = unescapeFilePath(output); |
|
1687 file.setFileName(output); |
|
1688 } |
|
1689 bool ret = UnixMakefileGenerator::openOutput(file, build); |
|
1690 ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); |
|
1691 Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); |
|
1692 return ret; |
|
1693 } |
|
1694 |
|
1695 /* This function is such a hack it is almost pointless, but it |
|
1696 eliminates the warning message from ProjectBuilder that the project |
|
1697 file is for an older version. I guess this could be used someday if |
|
1698 the format of the output is dependant upon the version of |
|
1699 ProjectBuilder as well. |
|
1700 */ |
|
1701 int |
|
1702 ProjectBuilderMakefileGenerator::pbuilderVersion() const |
|
1703 { |
|
1704 QString ret; |
|
1705 if(!project->isEmpty("QMAKE_PBUILDER_VERSION")) { |
|
1706 ret = project->first("QMAKE_PBUILDER_VERSION"); |
|
1707 } else { |
|
1708 QString version, version_plist = project->first("QMAKE_PBUILDER_VERSION_PLIST"); |
|
1709 if(version_plist.isEmpty()) { |
|
1710 #ifdef Q_OS_DARWIN |
|
1711 ret = QLatin1String("34"); |
|
1712 QCFType<CFURLRef> cfurl; |
|
1713 OSStatus err = LSFindApplicationForInfo(0, CFSTR("com.apple.Xcode"), 0, 0, &cfurl); |
|
1714 if (err == noErr) { |
|
1715 QCFType<CFBundleRef> bundle = CFBundleCreate(0, cfurl); |
|
1716 if (bundle) { |
|
1717 CFStringRef str = CFStringRef(CFBundleGetValueForInfoDictionaryKey(bundle, |
|
1718 CFSTR("CFBundleShortVersionString"))); |
|
1719 if (str) { |
|
1720 QStringList versions = QCFString::toQString(str).split(QLatin1Char('.')); |
|
1721 int versionMajor = versions.at(0).toInt(); |
|
1722 int versionMinor = versions.at(1).toInt(); |
|
1723 if (versionMajor >= 2) { |
|
1724 ret = QLatin1String("42"); |
|
1725 } else if (versionMajor == 1 && versionMinor >= 5) { |
|
1726 ret = QLatin1String("39"); |
|
1727 } |
|
1728 } |
|
1729 } |
|
1730 } |
|
1731 #else |
|
1732 if(exists("/Developer/Applications/Xcode.app/Contents/version.plist")) |
|
1733 version_plist = "/Developer/Applications/Xcode.app/Contents/version.plist"; |
|
1734 else |
|
1735 version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; |
|
1736 #endif |
|
1737 } else { |
|
1738 version_plist = version_plist.replace(QRegExp("\""), ""); |
|
1739 } |
|
1740 if (ret.isEmpty()) { |
|
1741 QFile version_file(version_plist); |
|
1742 if (version_file.open(QIODevice::ReadOnly)) { |
|
1743 debug_msg(1, "pbuilder: version.plist: Reading file: %s", version_plist.toLatin1().constData()); |
|
1744 QTextStream plist(&version_file); |
|
1745 |
|
1746 bool in_dict = false; |
|
1747 QString current_key; |
|
1748 QRegExp keyreg("^<key>(.*)</key>$"), stringreg("^<string>(.*)</string>$"); |
|
1749 while(!plist.atEnd()) { |
|
1750 QString line = plist.readLine().trimmed(); |
|
1751 if(line == "<dict>") |
|
1752 in_dict = true; |
|
1753 else if(line == "</dict>") |
|
1754 in_dict = false; |
|
1755 else if(in_dict) { |
|
1756 if(keyreg.exactMatch(line)) |
|
1757 current_key = keyreg.cap(1); |
|
1758 else if(current_key == "CFBundleShortVersionString" && stringreg.exactMatch(line)) |
|
1759 version = stringreg.cap(1); |
|
1760 } |
|
1761 } |
|
1762 plist.flush(); |
|
1763 version_file.close(); |
|
1764 } else { |
|
1765 debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.toLatin1().constData()); |
|
1766 } |
|
1767 if(version.isEmpty() && version_plist.contains("Xcode")) { |
|
1768 ret = "39"; |
|
1769 } else { |
|
1770 int versionMajor = version.left(1).toInt(); |
|
1771 if(versionMajor >= 2) |
|
1772 ret = "42"; |
|
1773 else if(version == "1.5") |
|
1774 ret = "39"; |
|
1775 else if(version == "1.1") |
|
1776 ret = "34"; |
|
1777 } |
|
1778 } |
|
1779 } |
|
1780 |
|
1781 if(!ret.isEmpty()) { |
|
1782 bool ok; |
|
1783 int int_ret = ret.toInt(&ok); |
|
1784 if(ok) { |
|
1785 debug_msg(1, "pbuilder: version.plist: Got version: %d", int_ret); |
|
1786 return int_ret; |
|
1787 } |
|
1788 } |
|
1789 debug_msg(1, "pbuilder: version.plist: Fallback to default version"); |
|
1790 return 42; //my fallback |
|
1791 } |
|
1792 |
|
1793 int |
|
1794 ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where) |
|
1795 { |
|
1796 int ret = 0; //absolute is the default.. |
|
1797 if(QDir::isRelativePath(unescapeFilePath(where))) |
|
1798 ret = 4; //relative |
|
1799 return ret; |
|
1800 } |
|
1801 |
|
1802 QString |
|
1803 ProjectBuilderMakefileGenerator::projectSuffix() const |
|
1804 { |
|
1805 const int pbVersion = pbuilderVersion(); |
|
1806 if(pbVersion >= 42) |
|
1807 return ".xcodeproj"; |
|
1808 else if(pbVersion >= 38) |
|
1809 return ".xcode"; |
|
1810 return ".pbproj"; |
|
1811 } |
|
1812 |
|
1813 QString |
|
1814 ProjectBuilderMakefileGenerator::pbxbuild() |
|
1815 { |
|
1816 if(exists("/usr/bin/pbbuild")) |
|
1817 return "pbbuild"; |
|
1818 if(exists("/usr/bin/xcodebuild")) |
|
1819 return "xcodebuild"; |
|
1820 return (pbuilderVersion() >= 38 ? "xcodebuild" : "pbxbuild"); |
|
1821 } |
|
1822 |
|
1823 QString |
|
1824 ProjectBuilderMakefileGenerator::escapeFilePath(const QString &path) const |
|
1825 { |
|
1826 #if 1 |
|
1827 //in the middle of generating a Makefile! |
|
1828 if(writingUnixMakefileGenerator) |
|
1829 return UnixMakefileGenerator::escapeFilePath(path); |
|
1830 |
|
1831 //generating stuff for the xml file! |
|
1832 QString ret = path; |
|
1833 if(!ret.isEmpty()) { |
|
1834 ret = unescapeFilePath(ret); |
|
1835 debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); |
|
1836 } |
|
1837 return ret; |
|
1838 #else |
|
1839 return UnixMakefileGenerator::escapeFilePath(path); |
|
1840 #endif |
|
1841 } |
|
1842 |
|
1843 QString |
|
1844 ProjectBuilderMakefileGenerator::writeSettings(QString var, QStringList vals, int flags, int indent_level) |
|
1845 { |
|
1846 QString ret; |
|
1847 const QString quote = (flags & SettingsNoQuote) ? "" : "\""; |
|
1848 const QString escape_quote = quote.isEmpty() ? "" : "\\" + quote; |
|
1849 QString newline = "\n"; |
|
1850 for(int i = 0; i < indent_level; ++i) |
|
1851 newline += "\t"; |
|
1852 if(flags & SettingsAsList) { |
|
1853 ret += var + " = (" + newline; |
|
1854 for(int i = 0, count = 0; i < vals.size(); ++i) { |
|
1855 QString val = vals.at(i); |
|
1856 if(!val.isEmpty()) { |
|
1857 if(count++ > 0) |
|
1858 ret += "," + newline; |
|
1859 ret += quote + val.replace(quote, escape_quote) + quote; |
|
1860 } |
|
1861 } |
|
1862 ret += ")"; |
|
1863 } else { |
|
1864 ret += var + " = " + quote; |
|
1865 for(int i = 0; i < vals.size(); ++i) { |
|
1866 QString val = vals.at(i); |
|
1867 // if(val.isEmpty()) |
|
1868 // val = quote + quote; |
|
1869 if(i) |
|
1870 ret += " "; |
|
1871 ret += val; |
|
1872 } |
|
1873 ret += quote; |
|
1874 } |
|
1875 return ret; |
|
1876 } |
|
1877 |
|
1878 QT_END_NAMESPACE |