author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Fri, 12 Mar 2010 15:46:37 +0200 | |
branch | RCL_3 |
changeset 5 | d3bac044e0f0 |
parent 4 | 3b1da2848fc7 |
permissions | -rw-r--r-- |
0 | 1 |
/**************************************************************************** |
2 |
** |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
3 |
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
0 | 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 |