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