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